{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import altair as alt\n",
    "import panel as pn\n",
    "\n",
    "from vega_datasets import data\n",
    "\n",
    "\n",
    "pn.extension(\"vega\", sizing_mode=\"stretch_width\", template=\"fast\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Styling Vega and Altair for Panel\n",
    "\n",
    "In this example we will show how to style Vega and Altair charts with Panel supporting the `default` and the `dark` theme.\n",
    "\n",
    "![VegaAltairStyle.gif](https://assets.holoviews.org/panel/thumbnails/gallery/styles/matplotlib-styles.gif)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get or set the theme\n",
    "\n",
    "When we use the Fast templates the theme will be available from the query args"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_theme():\n",
    "    return pn.state.session_args.get(\"theme\", [b'default'])[0].decode()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "theme=get_theme()\n",
    "theme"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Select a nice accent color\n",
    "\n",
    "Below we create some functionality to *cycle through* a list of nice accent colors."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "nice_accent_colors = [\n",
    "    (\"#00A170\", \"white\"), # Mint\n",
    "    (\"#DAA520\", \"white\"), # Golden Rod\n",
    "    (\"#F08080\", \"white\"), # Light Coral\n",
    "    (\"#4099da\", \"white\"), # Summery Sky\n",
    "    (\"#2F4F4F\", \"white\"), # Dark Slate Grey\n",
    "    (\"#A01346\", \"white\"), # Fast\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_nice_accent_color():\n",
    "    \"\"\"Returns the 'next' nice accent color\"\"\"\n",
    "    if not \"color_index\" in pn.state.cache:\n",
    "        pn.state.cache[\"color_index\"]=0\n",
    "    elif pn.state.cache[\"color_index\"]==len(nice_accent_colors)-1:\n",
    "        pn.state.cache[\"color_index\"]=0\n",
    "    else:\n",
    "        pn.state.cache[\"color_index\"]+=1\n",
    "    return nice_accent_colors[pn.state.cache[\"color_index\"]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "accent_color, color = get_nice_accent_color()\n",
    "pn.pane.Markdown(f\"# Color: {accent_color}\", background=accent_color, height=70, margin=0, style={\"color\": color, \"padding\": \"10px\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Vega and Vega-lite\n",
    "\n",
    "You can configure the style of `vega` and `vega-lite` via the `config` key. Please note that only `vega-lite` supports responsive behaviour by setting `width` and `height` to `container`. `vega` requires the `width` and `height` to be integers.\n",
    "\n",
    "See [Vega Themes](https://github.com/vega/vega-themes/) and the [Vega Themes Explorer App](https://vega.github.io/vega-themes) for more examples."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_vega_plot(theme=\"default\", accent_color=\"blue\"):\n",
    "    vegalite = {\n",
    "      \"$schema\": \"https://vega.github.io/schema/vega-lite/v5.json\",\n",
    "      \"description\": \"A simple bar chart with rounded corners at the end of the bar.\",\n",
    "      \"width\": \"container\",\n",
    "      \"height\": \"container\",\n",
    "      \"data\": {\n",
    "        \"values\": [\n",
    "          {\"a\": \"A\", \"b\": 28},\n",
    "          {\"a\": \"B\", \"b\": 55},\n",
    "          {\"a\": \"C\", \"b\": 43},\n",
    "          {\"a\": \"D\", \"b\": 91},\n",
    "          {\"a\": \"E\", \"b\": 81},\n",
    "          {\"a\": \"F\", \"b\": 53},\n",
    "          {\"a\": \"G\", \"b\": 19},\n",
    "          {\"a\": \"H\", \"b\": 87},\n",
    "          {\"a\": \"I\", \"b\": 52}\n",
    "        ]\n",
    "      },\n",
    "      \"mark\": {\"type\": \"bar\", \"cornerRadiusEnd\": 4, \"tooltip\": True},\n",
    "      \"encoding\": {\n",
    "        \"x\": {\"field\": \"a\", \"type\": \"ordinal\"},\n",
    "        \"y\": {\"field\": \"b\", \"type\": \"quantitative\"},\n",
    "        \"color\": {\"value\": accent_color},\n",
    "      }\n",
    "    }\n",
    "\n",
    "    if theme == \"dark\":\n",
    "        vegalite[\"config\"] = {\n",
    "            \"background\": \"#333\",\n",
    "            \"title\": {\"color\": \"#fff\"},\n",
    "            \"style\": {\"guide-label\": {\"fill\": \"#fff\"}, \"guide-title\": {\"fill\": \"#fff\"}},\n",
    "            \"axis\": {\"domainColor\": \"#fff\", \"gridColor\": \"#888\", \"tickColor\": \"#fff\"},\n",
    "        }\n",
    "    return vegalite"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "vega_plot = get_vega_plot(theme=theme, accent_color=accent_color)\n",
    "vega_pane = pn.pane.Vega(vega_plot, height=500, sizing_mode=\"stretch_both\", name=\"VEGA\")\n",
    "vega_pane"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Altair\n",
    "\n",
    "You can select the theme of Altair plots using [`altair.themes.enable`](https://altair-viz.github.io/user_guide/configuration.html#altair-themes) and the color using the `configure_mark` method.\n",
    "\n",
    "For more details see the \n",
    "\n",
    "- [Altair Customization Guide](https://altair-viz.github.io/user_guide/customization.html#customizing-visualizations)\n",
    "- [Altair Themes Guide](https://altair-viz.github.io/user_guide/configuration.html#altair-themes)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_altair_plot(theme=\"default\", accent_color=\"blue\"):\n",
    "    if theme == \"dark\":\n",
    "        alt.themes.enable(\"dark\")\n",
    "    else:\n",
    "        alt.themes.enable(\"default\")\n",
    "    return (\n",
    "        alt.Chart(data.cars())\n",
    "        .mark_circle(size=200)\n",
    "        .encode(\n",
    "            x='Horsepower:Q',\n",
    "            y='Miles_per_Gallon:Q',\n",
    "            tooltip=[\"Name\", \"Origin\", \"Horsepower\", \"Miles_per_Gallon\"],\n",
    "        )\n",
    "        .configure_mark(\n",
    "            color=accent_color\n",
    "        )\n",
    "        .properties(\n",
    "            height=\"container\",\n",
    "            width=\"container\",\n",
    "        )\n",
    "        .interactive()\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "altair_plot = get_altair_plot(theme=theme, accent_color=accent_color)\n",
    "altair_pane = pn.pane.Vega(altair_plot, height=500, sizing_mode=\"stretch_both\", name=\"ALTAIR\")\n",
    "altair_pane"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Layout and style the data app\n",
    "\n",
    "Note how we mark this component `.servable()` so that it shows up in our data app."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pn.Tabs(vega_pane, altair_pane).servable(title=\"Panel - Vega/ Altair with custom styling\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pn.state.template.param.update(accent_base_color=accent_color, header_background=accent_color)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can serve the app via `panel serve VegaAltairStyle.ipynb` and find it at http://localhost:5006/VegaAltairStyle. You should add the `--autoreload` flag while developing for *hot reloading*."
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
