{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### **Title**: CurveEdit Stream\n",
    "\n",
    "**Description**: A linked streams example demonstrating how to use the CurveEdit stream.\n",
    "\n",
    "**Dependencies**: Bokeh\n",
    "    \n",
    "**Backends**: [Bokeh](./CurveEdit.ipynb)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import holoviews as hv\n",
    "\n",
    "from holoviews import opts, streams\n",
    "from holoviews.plotting.links import DataLink\n",
    "\n",
    "hv.extension('bokeh')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The ``CurveEdit`` stream adds a bokeh tool to the source plot, which allows drawing, dragging and deleting points and making the drawn data available to Python. The tool supports the following actions:\n",
    "\n",
    "**Move vertex**\n",
    "    \n",
    "    Tap and drag an existing vertex, the vertex will be dropped once you let go of the mouse button.\n",
    "\n",
    "**Delete vertex**\n",
    "\n",
    "    Tap a vertex to select it then press BACKSPACE or DELETE key while the mouse is within the plot area."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As a simple example we will create a ``CurveEdit`` stream and attach it to a ``Curve`` with a simple timeseries. By using a `DataLink` we then link the tool to a ``Table``.\n",
    "\n",
    "If we select the PointDraw tool (<img src=\"https://bokeh.pydata.org/en/latest/_images/PointDraw.png\">) the vertices will appear and allow us to drag and delete vertex. We can also see the x/y position change in the table and edit it. To change the appearance of the vertices we can supply a `style` to the `CurveEdit` stream:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "curve = hv.Curve(np.random.randn(10).cumsum())\n",
    "\n",
    "curve_stream = streams.CurveEdit(data=curve.columns(), source=curve, style={'color': 'black', 'size': 10})\n",
    "\n",
    "table = hv.Table(curve).opts(editable=True)\n",
    "DataLink(curve, table)\n",
    "\n",
    "(curve + table).opts(\n",
    "    opts.Table(editable=True))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Whenever the data source is edited the data is synced with Python, both in the notebook and when deployed on the bokeh server. The data is made available as a dictionary of columns:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "curve_stream.data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Alternatively we can use the ``element`` property to get an Element containing the returned data:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "curve_stream.element"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
