{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import panel as pn\n",
    "\n",
    "pn.extension()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The ``DataFrame`` widget allows displaying and editing a pandas DataFrame.\n",
    "\n",
    "For more information about listening to widget events and laying out widgets refer to the [widgets user guide](../../user_guide/Widgets.ipynb). Alternatively you can learn how to build GUIs by declaring parameters independently of any specific widgets in the [param user guide](../../user_guide/Param.ipynb). To express interactivity entirely using Javascript without the need for a Python server take a look at the [links user guide](../../user_guide/Param.ipynb).\n",
    "\n",
    "#### Parameters:\n",
    "\n",
    "For layout and styling related parameters see the [customization user guide](../../user_guide/Customization.ipynb).\n",
    "\n",
    "##### Core\n",
    "\n",
    "* **``editors``** (``dict``):  A dictionary mapping from column name to a bokeh CellEditor instance, which overrides the default.\n",
    "* **``fit_columns``** (``boolean``, default=True): Whether columns should expand to the available width. \n",
    "* **``formatters``** (``dict``): A dictionary mapping from column name to a bokeh CellFormatter instance, which overrides the default.\n",
    "* **``row_height``** (``int``): The height of each table row.\n",
    "* **``selection``** (``list``) The currently selected rows \n",
    "* **``value``** (``pd.DataFrame``): The pandas DataFrame to display and edit\n",
    "* **``widths``** (``dict``): A dictionary mapping from column name to column width in the rendered table.\n",
    "\n",
    "##### Display\n",
    "\n",
    "* **``disabled``** (boolean): Whether the widget is editable\n",
    "* **``name``** (str): The title of the widget\n",
    "\n",
    "___"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The ``DataFrame`` widget renders an table which allows directly editing the contents of the dataframe with any changes being synced with Python. Note that it modifies the ``pd.DataFrame`` in place."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.DataFrame({'int': [1, 2, 3], 'float': [3.14, 6.28, 9.42], 'str': ['A', 'B', 'C']}, index=[1, 2, 3])\n",
    "\n",
    "df_widget = pn.widgets.DataFrame(df, name='DataFrame')\n",
    "\n",
    "df_widget"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "By default the widget will pick bokeh ``CellFormatter`` and ``CellEditor`` types appropriate to the dtype of the column. These may be overriden by explicit dictionaries mapping from the column name to the editor or formatter instance. For example below we create a ``SelectEditor`` instance to pick from four options in the ``str`` column and a ``NumberFormatter`` to customize the formatting of the float values:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from bokeh.models.widgets.tables import SelectEditor, NumberFormatter\n",
    "\n",
    "editor = SelectEditor(options=['A', 'B', 'C', 'D'])\n",
    "formatter = NumberFormatter(format='0.00000') \n",
    "\n",
    "table = pn.widgets.DataFrame(df, editors={'str': editor}, formatters={'float': formatter})\n",
    "table"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Once initialized the ``selection`` property will return the integer indexes of the selected rows and the ``selected_dataframe`` property will return a new DataFrame containing just the selected rows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "table.selection = [0, 2]\n",
    "\n",
    "table.selected_dataframe"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Controls\n",
    "\n",
    "The `DataFrame` widget 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": [
    "pn.Row(df_widget.controls(jslink=True), df_widget)"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
