Skip to content

Commit

Permalink
Add structure
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr committed Jan 15, 2024
1 parent 98e2459 commit 85768a8
Show file tree
Hide file tree
Showing 11 changed files with 193 additions and 11 deletions.
3 changes: 2 additions & 1 deletion doc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Panel is an [open-source](https://github.com/holoviz/panel/blob/main/LICENSE.txt

```{notebook} panel ../examples/homepage.ipynb
:disable_interactivity_warning: True
````
```

Panel makes it simple to:

Expand Down Expand Up @@ -192,6 +192,7 @@ alt: Quansight Logo
:caption: FOR USERS
getting_started/index
tutorials/index
how_to/index
explanation/index
reference/index
Expand Down
5 changes: 5 additions & 0 deletions doc/tutorials/components.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Components

```{notebook} panel ../../examples/tutorials/02_Components.ipynb
:disable_interactivity_warning: True
```
5 changes: 5 additions & 0 deletions doc/tutorials/development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Effective Development

```{notebook} panel ../../examples/tutorials/04_Development.ipynb
:disable_interactivity_warning: True
````
73 changes: 73 additions & 0 deletions doc/tutorials/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Tutorials

The [getting started guides](../getting_started/index.md) aims to get you set up with Panel and introduces you to some of the core concepts. The tutorials on the other hand will take you from being a beginner and guide you through your learning.

---

::::{grid} 1 2 2 3
:gutter: 1 1 1 2

:::{grid-item-card} {octicon}`plug;2.5em;sd-mr-1` Param
:link: param
:link-type: doc

Panel and other projects in the HoloViz ecosystem all build on Param. In this section you will learn the basic concepts behind Param that you need to know to become an effective user of Panel.
:::

:::{grid-item-card} {octicon}`container;2.5em;sd-mr-1` Components
:link: components
:link-type: doc

Panel is a library that provides a lot of object types and while building an app, even a simple one, you will create and interact with many of them. In this section you will get a high-level overview of the different component types Panel offers and how to use them.
:::

:::{grid-item-card} {octicon}`pulse;2.5em;sd-mr-1` Interactivity
:link: interactivity
:link-type: doc

In this section you learn how to leverage Parameters and dependencies on parameters to add interactivity. In particular we will focus on implementing interactivity through reactivity, rather than the more imperative style of programming you might be used to from other UI frameworks.
:::

:::{grid-item-card} {octicon}`browser;2.5em;sd-mr-1` Effective Development
:link: development
:link-type: doc

In this section we will introduce you to the most important concepts you need to know to become an effective Panel developer in notebooks and your favorite editor.
:::

:::{grid-item-card} {octicon}`rows;2.5em;sd-mr-1` Layouts
:link: layouts
:link-type: doc

In this section we will discover how layouts and sizing works in Panel, taking you through the difference between inherent sizing, fixed sizing and responsive sizing and then cover responsive layouts.
:::

:::{grid-item-card} {octicon}`code;2.5em;sd-mr-1` Structuring Applications
:link: structure
:link-type: doc

In this section we will take you through the process of structuring a more complex application, discussing different approaches for managing reactivity and how to create a composable architecture for your applications.
:::

:::{grid-item-card} {octicon}`paintbrush;2.5em;sd-mr-1` Styling
:link: styling
:link-type: doc

In this section we will take you through the process of structuring a more complex application, discussing different approaches for managing reactivity and how to create a composable architecture for your applications.
:::

::::

```{toctree}
:titlesonly:
:hidden:
:maxdepth: 2
param
components
interactivity
development
layouts
structure
styling
```
5 changes: 5 additions & 0 deletions doc/tutorials/interactivity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Interactivity

```{notebook} panel ../../examples/tutorials/03_Interactivity.ipynb
:disable_interactivity_warning: True
```
5 changes: 5 additions & 0 deletions doc/tutorials/layouts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Layouts

```{notebook} panel ../../examples/tutorials/05_Layouts.ipynb
:disable_interactivity_warning: True
````
5 changes: 5 additions & 0 deletions doc/tutorials/param.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Param

```{notebook} panel ../../examples/tutorials/01_Param.ipynb
:disable_interactivity_warning: True
````
5 changes: 5 additions & 0 deletions doc/tutorials/structure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Structuring Applications

```{notebook} panel ../../examples/tutorials/06_Structuring_Code.ipynb
:disable_interactivity_warning: True
````
5 changes: 5 additions & 0 deletions doc/tutorials/styling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Styling

```{notebook} panel ../../examples/tutorials/07_Styling.ipynb
:disable_interactivity_warning: True
````
2 changes: 1 addition & 1 deletion examples/tutorials/04_Development.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"\n",
"#### Debugging and effective development in VSCode and JupyterLab\n",
"\n",
"When you develop a web app it is important for you to often check that the code you write produces the user interface you expect, the faster you get this feedback, the faster you will develop your app and improve your Panel skills. It's also important for you to be able to use a coding environment you are comfortable with. To this end, Panel offers very good support for Jupyter Notebooks (Classic and JupyterLab) and editors like Visual Studio Code, which are the two environments we will cover in this guide.\n",
" It's also important for you to be able to use a coding environment you are comfortable with. To this end, Panel offers very good support for Jupyter Notebooks (Classic and JupyterLab) and editors like Visual Studio Code, which are the two environments we will cover in this guide.\n",
"\n",
":::"
]
Expand Down
91 changes: 82 additions & 9 deletions examples/tutorials/06_Structuring_Code.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,29 @@
"id": "de72441f-bbf8-4af6-b1d7-73b4f70b0d1e",
"metadata": {},
"source": [
"## Composing Parameterized Classes\n",
"## Building the app\n",
"\n",
"When building a complex application object-oriented programming usually suggests to build compositional classes, each with a well defined role. Let us explore one such pattern:"
"Now that we have covered the preliminaries lets actually build an app that more closely resembles something you might actually use in production.\n",
"\n",
"When building a more complex application we generally recommend using a class based construction and following best practices for object-oriented programming, specifically composition. \n",
"\n",
"One particular design pattern that has proven quite successful across a wide range of use cases is something we will put into effect here, specifically we will construct:\n",
"\n",
"- A `DataStore` that loads data from the catalog and defines a variable number of filters.\n",
"- A `View` component that consumes the data and then displays it."
]
},
{
"cell_type": "markdown",
"id": "878413b1-23a5-49fd-88af-4c75e8968696",
"metadata": {},
"source": [
"#### The DataStore\n",
"\n",
"We won't worry too much about the implementation details of this data store implementation but it's worth noting at a high-level it does a few simple things:\n",
"\n",
"1. Initialize a data catalog using the automatic access controls.\n",
"2. Load a `table` from the data store and automatically generating a set of filters for each source."
]
},
{
Expand Down Expand Up @@ -91,11 +111,7 @@
" return \n",
" \n",
" def __panel__(self):\n",
" return pn.Column('## Filters', *self._widgets, stylesheets=[CARD_STYLE.format(padding='5px 10px')], margin=10)\n",
" \n",
"class View(Viewer):\n",
"\n",
" data_store = param.ClassSelector(class_=DataStore)"
" return pn.Column('## Filters', *self._widgets, stylesheets=[CARD_STYLE.format(padding='5px 10px')], margin=10)\n"
]
},
{
Expand All @@ -106,6 +122,14 @@
"Here we declared a `DataStore` class that will be responsible for loading some data and transforming it in various ways and a `View` class that holds a reference to the `DataStore` as a parameter. Now we can have any number of concrete `View` classes that consume data from the DataStore and render it in any number of ways:"
]
},
{
"cell_type": "markdown",
"id": "8d03ee78-e85e-4078-9d7e-92d9c61cdf4e",
"metadata": {},
"source": [
"### The Views"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -119,6 +143,10 @@
"import holoviews as hv\n",
"import hvplot.pandas\n",
"\n",
"class View(Viewer):\n",
"\n",
" data_store = param.ClassSelector(class_=DataStore)\n",
"\n",
"class Table(View):\n",
" \n",
" columns = param.List(default=['p_name', 'p_year', 't_state', 't_county', 't_manu', 't_cap', 'p_cap'])\n",
Expand Down Expand Up @@ -168,16 +196,47 @@
" pn.indicators.Number(\n",
" value=self.data_store.avg_rotor_diameter, name='Avg. Rotor Diameter (m)', format='{value:,.2f}', **style\n",
" ),\n",
" \n",
" )"
]
},
{
"cell_type": "markdown",
"id": "5742bcdd-6288-4510-9f7e-0f71f82aeb95",
"metadata": {},
"source": [
"The beauty of this compositional approach to constructing application components is that they are now usable in multiple contexts, e.g. you can use them in a notebook:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b72587c0-6e87-4715-ae43-8eb4488d5c3d",
"metadata": {},
"outputs": [],
"source": [
"data_url = 'https://datasets.holoviz.org/windturbines/v1/windturbines.parq'\n",
"\n",
"turbines = pd.read_parquet(data_url)\n",
"\n",
"ds = DataStore(data=turbines, filters=['p_year', 'p_cap', 't_manu'])\n",
"\n",
"pn.Row(\n",
" ds,\n",
" pn.Tabs(\n",
" ('Table', Table(data_store=ds)),\n",
" ('Histogram', Histogram(data_store=ds)),\n",
" ('Indicators', Indicators(data_store=ds)),\n",
" sizing_mode='stretch_width',\n",
" )\n",
")"
]
},
{
"cell_type": "markdown",
"id": "565d7dcc-37ed-470d-9d80-e9b075571c52",
"metadata": {},
"source": [
"Lastly we can create an `App` class that coordinates the creation of the `View` components and lays them out on the page."
"Or we can coordinate these components inside of `App` class that handles the creation of the `View` components and lays them out on the pag or template:"
]
},
{
Expand Down Expand Up @@ -238,6 +297,20 @@
"\n",
"app.servable()"
]
},
{
"cell_type": "markdown",
"id": "bf54788c-730c-48b5-8ab2-5df7f639ebda",
"metadata": {},
"source": [
"<div class=\"header-box\" style=\"box-shadow: rgba(50, 50, 93, 0.25) 0px 6px 12px -2px, rgba(0, 0, 0, 0.3) 0px 3px 7px -3px; padding: 5px 10px; border-left: 4px solid green;\">\n",
"\n",
"### Exercise\n",
"\n",
"Now it is time to get started for real and extend the existing application. Build your own `View` and add it to the `App`, then deploy it. \n",
"\n",
"</div>"
]
}
],
"metadata": {
Expand Down

0 comments on commit 85768a8

Please sign in to comment.