{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import panel as pn\n",
    "pn.extension('echarts')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The ``ECharts`` pane renders [Apache ECharts](https://echarts.apache.org/en/index.html) and [pyecharts](https://pyecharts.org/#/) plots inside Panel. Note that to use the ``ECharts`` pane in the notebook the Panel extension has to be loaded with 'echarts' as an argument to ensure that echarts.js is initialized. \n",
    "\n",
    "#### Parameters:\n",
    "\n",
    "For layout and styling related parameters see the [customization user guide](../../user_guide/Customization.ipynb).\n",
    "\n",
    "* **``object``** (dict): An ECharts plot specification expressed as a Python dictionary, which is then converted to JSON. Or a pyecharts chart like `pyecharts.charts.Bar`.\n",
    "* **``renderer``** (str): Whether to render with HTML 'canvas' (default) or 'svg'\n",
    "* **``theme``** (str): Theme to apply to plots (one of 'default', 'dark', 'light')\n",
    "___"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Lets try the ``ECharts`` pane support for ECharts specs in its raw form (i.e. a dictionary), e.g. here we declare a bar plot:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "echart = {\n",
    "    'title': {\n",
    "        'text': 'ECharts entry example'\n",
    "    },\n",
    "    'tooltip': {},\n",
    "    'legend': {\n",
    "        'data':['Sales']\n",
    "    },\n",
    "    'xAxis': {\n",
    "        'data': [\"shirt\",\"cardign\",\"chiffon shirt\",\"pants\",\"heels\",\"socks\"]\n",
    "    },\n",
    "    'yAxis': {},\n",
    "    'series': [{\n",
    "        'name': 'Sales',\n",
    "        'type': 'bar',\n",
    "        'data': [5, 20, 36, 10, 10, 20]\n",
    "    }],\n",
    "};\n",
    "echart_pane = pn.pane.ECharts(echart, height=480, width=640)\n",
    "echart_pane"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Like all other panes, the ``ECharts`` pane ``object`` can be updated, either in place and triggering an update:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "echart['series'] = [dict(echart['series'][0], type= 'line')]\n",
    "echart_pane.param.trigger('object')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Vega specification can also be responsively sized by declaring the width or height to match the container:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "responsive_spec = dict(echart, responsive=True)\n",
    "\n",
    "pn.pane.ECharts(responsive_spec, height=400)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The ECharts pane also hass support for pyecharts. For example, we can pass a `pyecharts.charts.Bar` chart directly the `ECharts` pane.  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pyecharts.charts import Bar\n",
    "\n",
    "bar1 = pn.widgets.IntSlider(start=1, end=100, value=50)\n",
    "bar2 = pn.widgets.IntSlider(start=1, end=100, value=50)\n",
    "\n",
    "@pn.depends(bar1.param.value, bar2.param.value)\n",
    "def plot(bar1, bar2):\n",
    "    my_plot= (Bar()\n",
    "        .add_xaxis(['Helicoptors', 'Planes'])\n",
    "        .add_yaxis('Total In Flight', [bar1, bar2])\n",
    "    )\n",
    "    return pn.pane.ECharts(my_plot, width=500, height=250)\n",
    "pn.Row(pn.Column(bar1, bar2), plot).servable()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The ECharts library supports a wide range of chart types and since the plots are expressed using JSON datastructures we can easily update the data and then emit change events to update the charts:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "gauge = {\n",
    "    'tooltip': {\n",
    "        'formatter': '{a} <br/>{b} : {c}%'\n",
    "    },\n",
    "    'series': [\n",
    "        {\n",
    "            'name': 'Gauge',\n",
    "            'type': 'gauge',\n",
    "            'detail': {'formatter': '{value}%'},\n",
    "            'data': [{'value': 50, 'name': 'Value'}]\n",
    "        }\n",
    "    ]\n",
    "};\n",
    "gauge_pane = pn.pane.ECharts(gauge, width=400, height=400)\n",
    "\n",
    "slider = pn.widgets.IntSlider(start=0, end=100)\n",
    "\n",
    "slider.jscallback(args={'gauge': gauge_pane}, value=\"\"\"\n",
    "gauge.data.series[0].data[0].value = cb_obj.value\n",
    "gauge.properties.data.change.emit()\n",
    "\"\"\")\n",
    "\n",
    "pn.Column(slider, gauge_pane)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Controls\n",
    "\n",
    "The `EChart` pane 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(gauge_pane.controls(jslink=True), gauge_pane)"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
