{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Demonstrates loading deck.gl as external JSS and CSS components, rendering it as part of an app, and then linking it to Panel widgets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import panel as pn\n",
    "\n",
    "js_files = {'deck': 'https://unpkg.com/deck.gl@^6.0.0/deckgl.min.js',\n",
    "            'mapboxgl': 'https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.js'}\n",
    "css_files = ['https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.css']\n",
    "\n",
    "pn.extension(js_files=js_files, css_files=css_files)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, let's declare the cities we are interested in using Python:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cities = [\n",
    "    {\"city\":\"San Francisco\",\"state\":\"California\",\"latitude\":37.7751,\"longitude\":-122.4193},\n",
    "    {\"city\":\"New York\",\"state\":\"New York\",\"latitude\":40.6643,\"longitude\":-73.9385},\n",
    "    {\"city\":\"Los Angeles\",\"state\":\"California\",\"latitude\":34.051597,\"longitude\":-118.244263},\n",
    "    {\"city\":\"London\",\"state\":\"United Kingdom\",\"latitude\":51.5074,\"longitude\":-0.1278},\n",
    "    {\"city\":\"Hyderabad\",\"state\":\"India\",\"latitude\":17.3850,\"longitude\":78.4867}]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, let's declare an HTML `<div>` to render the plot into, then define the deck.gl script code to render a plot for those cities."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "html = \"\"\"\n",
    "<div id=\"deckgl-container\" style=\"width: 800px; height: 500px;\"></div>\n",
    "\n",
    "<script type=\"text/javascript\">\n",
    "// Data\n",
    "var CITIES = %s;\n",
    "var deckgl = new deck.DeckGL({\n",
    "  container: 'deckgl-container',\n",
    "  mapboxApiAccessToken: 'pk.eyJ1IjoicGhpbGlwcGpmciIsImEiOiJjajM2bnE4MWcwMDNxMzNvMHMzcGV3NjlnIn0.976fZ1azCrTh50lEdZTpSg',\n",
    "  longitude: CITIES[0].longitude,\n",
    "  latitude: CITIES[0].latitude,\n",
    "  zoom: 10,\n",
    "  layers: [\n",
    "    new deck.ScatterplotLayer({\n",
    "      data: CITIES,\n",
    "      getPosition: d => [d.longitude, d.latitude],\n",
    "      radiusMinPixels: 10\n",
    "    })\n",
    "  ]\n",
    "});\n",
    "</script>\n",
    "\"\"\" % cities\n",
    "deckgl = pn.pane.HTML(html, height=500, width=800)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next we can declare a Panel widget and define a ``jslink`` to update the deck.gl plot whenever the widget state changes. The example is adapted from http://deck.gl/showcases/gallery/viewport-transition but replaces D3 widgets with Panel-based widgets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "widget = pn.widgets.RadioButtonGroup(options=[c[\"city\"] for c in cities])\n",
    "\n",
    "update_city = \"\"\"\n",
    "var d = CITIES[source.active];\n",
    "deckgl.setProps({\n",
    "  viewState: {\n",
    "    longitude: d.longitude,\n",
    "    latitude: d.latitude,\n",
    "    zoom: 10,\n",
    "    transitionInterpolator: new deck.FlyToInterpolator(),\n",
    "    transitionDuration: 5000\n",
    "  }\n",
    "});\n",
    "\"\"\"\n",
    "\n",
    "widget.jslink(deckgl, code={'active': update_city});\n",
    "\n",
    "pn.Column(widget, deckgl)"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
