{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import panel as pn\n",
    "\n",
    "from bokeh.sampledata.autompg import autompg\n",
    "from io import StringIO\n",
    "\n",
    "pn.extension(sizing_mode=\"stretch_width\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "years = pn.widgets.MultiChoice(\n",
    "    name='Years', options=list(autompg.yr.unique()), margin=(0, 20, 0, 0)\n",
    ")\n",
    "mpg = pn.widgets.RangeSlider(\n",
    "    name='Mile per Gallon', start=autompg.mpg.min(), end=autompg.mpg.max()\n",
    ")\n",
    "\n",
    "@pn.depends(years, mpg)\n",
    "def filtered_mpg(yrs, mpg):\n",
    "    df = autompg\n",
    "    if years.value:\n",
    "        df = autompg[autompg.yr.isin(yrs)]\n",
    "    return df[(df.mpg >= mpg[0]) & (df.mpg <= mpg[1])]\n",
    "\n",
    "@pn.depends(years, mpg)\n",
    "def filtered_file(yr, mpg):\n",
    "    df = filtered_mpg(yr, mpg)\n",
    "    sio = StringIO()\n",
    "    df.to_csv(sio)\n",
    "    sio.seek(0)\n",
    "    return sio\n",
    "\n",
    "fd = pn.widgets.FileDownload(\n",
    "    callback=filtered_file, filename='filtered_autompg.csv'\n",
    ")\n",
    "\n",
    "pn.Column(pn.Row(years, mpg), fd, pn.panel(filtered_mpg, width=600), width=600)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## App\n",
    "\n",
    "Lets wrap it into nice template that can be served via `panel serve save_filtered_df.ipynb`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pn.template.FastListTemplate(\n",
    "    site=\"Panel\", \n",
    "    title=\"Save Filtered Dataframe\", \n",
    "    main=[\n",
    "        pn.Column(\n",
    "            \"This app demonstrates how to **filter and download a Pandas DataFrame**.\",\n",
    "            pn.pane.HTML(\"<div style='font-size: 100px;text-align: center'>🐼</div>\", height=75, margin=(50,5,10,5)),\n",
    "        ),\n",
    "        pn.Column(years, mpg, fd), \n",
    "        pn.Column(filtered_mpg, height=600, scroll=True),\n",
    "    ], main_max_width=\"768px\",\n",
    ").servable();"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
