Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
holoviz
GitHub Repository: holoviz/panel
Path: blob/main/doc/how_to/custom_components/esm/dataframe.md
2012 views

Rendering DataFrames using ESM components

In this guide we will show you how to implement ESM components with a DataFrame parameter.

Creating a JSComponent

In this example we will show you how to create a custom DataFrame Pane. The example will be based on the GridJS table.

import random import pandas as pd import param import panel as pn from panel.custom import JSComponent class GridJS(JSComponent): object = param.DataFrame() _esm = """ import * as gridjs from "https://esm.sh/[email protected]" function get_config(model) { const data = model.object const columns = Object.keys(data).filter(key => key !== "index"); const rows = [] for (let index=0; index < data["index"].shape[0]; index++) { const row = columns.map(key => data[key][index]) rows.push(row) } return {columns: columns, data: rows, resizable: true, sort: true} } export function render({model, el}) { console.log(model.object) const config = get_config(model) console.log(config) const grid = new gridjs.Grid(config).render(el) model.on('object', () => grid.updateConfig(get_config(model)).forceRender()) } """ __css__ = [ "https://unpkg.com/gridjs/dist/theme/mermaid.min.css" ] def data(event): return pd.DataFrame([ ["John", "[email protected]", "(353) 01 222 3333", random.uniform(0, 1)], ["Mark", "[email protected]", "(01) 22 888 4444", random.uniform(0, 1)], ["Eoin", "[email protected]", "0097 22 654 00033", random.uniform(0, 1)], ["Sarah", "[email protected]", "+322 876 1233", random.uniform(0, 1)], ["Afshin", "[email protected]", "(353) 22 87 8356", random.uniform(0, 1)] ], columns= ["Name", "Email", "Phone Number", "Random"]) update_button = pn.widgets.Button(name="UPDATE", button_type="primary") grid = GridJS(object=pn.bind(data, update_button), sizing_mode="stretch_width") pn.Column(update_button, grid).servable()

The main challenge of creating this component is understanding the structure of data.value and how it can be converted to a format (config) that gridjs.Grid accepts.

To help you understand what the data.value and config values looks like, I've logged them to the browser console using console.log.

DataFrame in the console

Creating a ReactComponent

Now let's see how to implement the same thing using the GridJS React integration.

import random import pandas as pd import param import panel as pn from panel.custom import PaneBase, ReactComponent class GridJS(ReactComponent): object = param.DataFrame() _esm = """ import { useEffect, useState } from "react" import { Grid } from "https://esm.sh/[email protected]" function get_config(data) { const columns = Object.keys(data).filter(key => key !== "index"); const rows = [] for (let index=0; index < data["index"].shape[0]; index++) { const row = columns.map(key => data[key][index]) rows.push(row) } return {columns: columns, data: rows, resizable: true, sort: true} } export function render({model, el}) { const [data] = model.useState("object") const [config, setConfig] = useState(get_config(data)) useEffect(() => { const newConfig = get_config(data); setConfig(newConfig); }, [data]) return <Grid {...config}></Grid> } """ __css__ = [ "https://unpkg.com/gridjs/dist/theme/mermaid.min.css" ] def data(event): return pd.DataFrame([ ["John", "[email protected]", "(353) 01 222 3333", random.uniform(0, 1)], ["Mark", "[email protected]", "(01) 22 888 4444", random.uniform(0, 1)], ["Eoin", "[email protected]", "0097 22 654 00033", random.uniform(0, 1)], ["Sarah", "[email protected]", "+322 876 1233", random.uniform(0, 1)], ["Afshin", "[email protected]", "(353) 22 87 8356", random.uniform(0, 1)] ], columns= ["Name", "Email", "Phone Number", "Random"]) update_button = pn.widgets.Button(name="UPDATE", button_type="primary") grid = GridJS(object=pn.bind(data, update_button), sizing_mode="stretch_width") pn.Column(update_button, grid).servable()