{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import panel as pn\n",
    "import pandas as pd\n",
    "import hvplot.pandas\n",
    "import time\n",
    "\n",
    "pn.extension(sizing_mode=\"stretch_width\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Defer loading of the data and populating the widgets until the page is rendered:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "stocks_url = 'https://raw.githubusercontent.com/vega/datalib/master/test/data/stocks.csv'\n",
    "\n",
    "select_ticker = pn.widgets.Select(name='Stock Ticker', width=250, sizing_mode=\"fixed\")\n",
    "\n",
    "def load_data():\n",
    "    if 'stocks' not in pn.state.cache: \n",
    "        pn.state.cache['stocks'] = df = pd.read_csv(stocks_url, parse_dates=['date']).set_index('symbol')\n",
    "    else:\n",
    "        df = pn.state.cache['stocks']\n",
    "    symbols = list(df.index.unique())\n",
    "    select_ticker.options = symbols\n",
    "    select_ticker.value = symbols[0]\n",
    "    \n",
    "pn.state.onload(load_data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If `'stocks'` is not yet in cache we show a spinner widget, otherwise let us plot the data:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@pn.depends(select_ticker)\n",
    "def plot_ticker(ticker):\n",
    "    if 'stocks' not in pn.state.cache or not ticker:\n",
    "        return pn.indicators.LoadingSpinner(value=True)\n",
    "    time.sleep(0.5)\n",
    "    return pn.state.cache['stocks'].loc[ticker].hvplot.line('date', 'price', color=\"#C01754\", line_width=6)\n",
    "\n",
    "pn.Row(select_ticker, plot_ticker)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## App\n",
    "\n",
    "Lets wrap it into nice template that can be served via `panel serve defer_data_load.ipynb`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pn.template.FastListTemplate(\n",
    "    site=\"Panel\", \n",
    "    title=\"Defer Data Load\", \n",
    "    sidebar=[select_ticker], \n",
    "    main=[\n",
    "        \"This app demonstrates how to **defer the loading** of the data and population of the widgets until the page is rendered\",\n",
    "        plot_ticker,\n",
    "    ]\n",
    ").servable();"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
