{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### **Title**: PolyDraw\n",
    "\n",
    "**Description**: A linked streams example demonstrating how to use the PolyDraw stream.\n",
    "\n",
    "**Dependencies**: Bokeh\n",
    "\n",
    "**Backends**: [Bokeh](./PolyDraw.ipynb)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import holoviews as hv\n",
    "from holoviews import opts, streams\n",
    "\n",
    "hv.extension('bokeh')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The ``PolyDraw`` stream adds a bokeh tool to the source plot, which allows drawing, dragging and deleting polygons and making the drawn data available to Python. The tool supports the following actions:\n",
    "\n",
    "**Add patch/multi-line**\n",
    "\n",
    "    Double tap to add the first vertex, then use tap to add each subsequent vertex, to finalize the draw action double tap to insert the final vertex or press the ESC key to stop drawing.\n",
    "\n",
    "**Move patch/multi-line**\n",
    "\n",
    "    Tap and drag an existing patch/multi-line; the point will be dropped once you let go of the mouse button.\n",
    "\n",
    "**Delete patch/multi-line**\n",
    "\n",
    "    Tap a patch/multi-line to select it then press BACKSPACE key while the mouse is within the plot area.\n",
    "    \n",
    "### Properties\n",
    "\n",
    "* **``drag``** (boolean): Whether to enable dragging of paths and polygons\n",
    "* **``empty_value``**: Value to add to non-coordinate columns when adding new path or polygon\n",
    "* **``num_objects``** (int): Maximum number of paths or polygons to draw before deleting the oldest object\n",
    "* **``show_vertices``** (boolean): Whether to show the vertices of the paths or polygons\n",
    "* **``styles``** (dict): Dictionary of style properties (e.g. line_color, line_width etc.) to apply to each path and polygon. If values are lists the values will cycle over the values) \n",
    "* **``vertex_style``** (dict): Dictionary of style properties (e.g. fill_color, line_width etc.) to apply to vertices if ``show_vertices`` enabled"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As a simple example we will create simple ``Path`` and ``Polygons`` elements and attach each to a ``PolyDraw`` stream. We will also enable the ``drag`` option on the stream to enable dragging of existing glyphs. Additionally we can enable the ``show_vertices`` option which shows the vertices of the drawn polygons/lines and adds the ability to snap to them. Finally the ``num_objects`` option limits the number of lines/polygons that can be drawn by dropping the first glyph when the limit is exceeded. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "path = hv.Path([[(1, 5), (9, 5)]])\n",
    "poly = hv.Polygons([[(2, 2), (5, 8), (8, 2)]])\n",
    "path_stream = streams.PolyDraw(source=path, drag=True, show_vertices=True)\n",
    "poly_stream = streams.PolyDraw(source=poly, drag=True, num_objects=4,\n",
    "                               show_vertices=True, styles={\n",
    "                                   'fill_color': ['red', 'green', 'blue']\n",
    "                               })\n",
    "\n",
    "(path * poly).opts(\n",
    "    opts.Path(color='red', height=400, line_width=5, width=400),\n",
    "    opts.Polygons(fill_alpha=0.3, active_tools=['poly_draw']))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<center><img src=\"https://assets.holoviews.org/gifs/examples/streams/bokeh/poly_draw.gif\" width=400></center>"
   ]
  },
  {
   "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": [
    "path_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": [
    "path_stream.element * poly_stream.element"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
