Panel応用編 第7回: カスタムコンポーネントによるPanelの拡張

Python
この記事は約8分で読めます。

こんにちは、JS2IIUです。今回はアイキャッチ画像の文字がはみ出てしまいました。今回もよろしくお願いします。

はじめに

Panelは、豊富なUIコンポーネントを提供していますが、時にはカスタムウィジェットや独自のインタラクションが必要になることもあります。本記事では、Panelの拡張方法について解説します。具体的には、ReactやJavaScriptを使ってカスタムコンポーネントを作成し、それをPanelアプリに組み込む方法を紹介します。これにより、標準のUIコンポーネントを超えた柔軟な機能を実装できます。

Component Gallery — Panel v1.8.1

Panelの標準コンポーネントの限界とカスタマイズの必要性

Panelの標準コンポーネントには、ボタン、テキストフィールド、スライダー、チャートなど、多くの便利なUI要素が揃っています。しかし、次のような場合には、標準コンポーネントだけでは要件を満たせないことがあります。

  • 特定のライブラリ(例: D3.js、Leaflet)と連携した可視化を実現したい場合
  • ユーザーインタラクションをカスタマイズしたい場合
  • 独自のデザインやスタイルを適用したい場合

こうした要件に対応するため、JavaScriptやReactなどの外部ライブラリを活用し、Panelに新しいコンポーネントを追加できます。

カスタムJavaScriptコンポーネントの作成

まず、JavaScriptを使ってカスタムコンポーネントを作成する基本的な方法を紹介します。Panelは、pn.pane.HTMLを使って任意のHTMLやJavaScriptコードを表示できるため、独自のウィジェットを簡単に実装できます。

例1: シンプルなJavaScriptコンポーネント

次の例では、JavaScriptを使ってリアルタイムの時計を作成し、Panelアプリケーション内で表示します。

注)PythonとBokehのバージョンがミスマッチの場合に時計が表示されないことがあるようです。この問題を回避できるか、調査中です。ブラウザのコンソールに"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing"というエラーが出ている場合があります。

import panel as pn

pn.extension()

# JavaScriptコード
js_code = """
function updateClock() {
    const now = new Date();
    const hours = String(now.getHours()).padStart(2, '0');
    const minutes = String(now.getMinutes()).padStart(2, '0');
    const seconds = String(now.getSeconds()).padStart(2, '0');
    const timeString = `${hours}:${minutes}:${seconds}`;
    
    document.getElementById('clock').textContent = timeString;
}

// 初回の更新と1秒ごとの更新
updateClock();
setInterval(updateClock, 1000);
</script>
"""

# JavaScriptコードをHTMLパネルとして表示
clock_pane = pn.pane.HTML(js_code, height=100, safe_embed=True)

# レイアウトの表示
layout = pn.Column("## Real-Time Clock", clock_pane)
layout.servable()
pn.serve(layout)
  • pn.pane.HTML を使って任意のHTMLやJavaScriptコードを表示できます。
  • setInterval を使い、毎秒時計を更新するJavaScriptを実行しています。

このシンプルなコンポーネントにより、Panelアプリ内に動的な時計が表示されます。

ReactとPanelの統合

Reactは、モダンなWebアプリケーション開発に広く使われるフレームワークで、インタラクティブなUIコンポーネントを作成するのに適しています。次に、Reactを使ってカスタムコンポーネントを作成し、それをPanelに組み込む方法を紹介します。

例2: ReactコンポーネントのPanelへの組み込み

以下の手順でReactをPanelに統合する方法を見ていきます。

手順1: Reactのインストール

まず、Reactと関連ライブラリをインストールする必要があります。以下のコマンドを実行してインストールしてください。

Linux:

npm install react react-dom

Mac:

こちらからNode.jsをダウンロードします。

Node.js — Run JavaScript Everywhere
Node.js® is a free, open-source, cross-platform JavaScript runtime environment that lets developers create servers, web apps, command line tools and s...
npx create-react-app my-app

Windows:

こちらの記事を参照して下さい。

WindowsでReactの環境構築をしてみる - Qiita
はじめに 今回は、自分のWindowsの環境でReactの環境構築をしたときの備忘録になります。 お付き合い頂ければ幸いです。 #Reactの環境構築に必要なもの 今回は、Facebookが開発しているcreate-react-appというコマンドを使って、サクッとRea...

手順2: Reactコンポーネントの作成

次に、Reactを使ってカスタムコンポーネントを作成し、JavaScriptとしてPanelに組み込みます。

import panel as pn

pn.extension()

# Reactコンポーネントの作成
react_code = """
<div id="root"></div>
<script type="text/babel">
  class MyComponent extends React.Component {
    constructor(props) {
      super(props);
      this.state = { count: 0 };
    }

    increment = () => {
      this.setState({ count: this.state.count + 1 });
    }

    render() {
      return (
        <div>
          <h1>{this.state.count}</h1>
          <button onClick={this.increment}>Increment</button>
        </div>
      );
    }
  }

  ReactDOM.render(<MyComponent />, document.getElementById('root'));
</script>
"""

# ReactコンポーネントをHTMLパネルとして表示
react_pane = pn.pane.HTML(react_code, height=200)

# レイアウトの表示
layout = pn.Column("## React Component in Panel", react_pane)
layout.servable()
pn.serve(layout)
  • pn.pane.HTML を使って、ReactのコードをPanel内で表示しています。
  • ReactDOM.render を使い、作成したReactコンポーネントをDOM要素にマウントします。
  • MyComponent はカスタムReactコンポーネントで、ボタンをクリックするたびにカウントが増えるシンプルな例です。

このコードにより、Reactを使ってインタラクティブなカスタムコンポーネントをPanelに統合できます。

Bokeh拡張によるカスタムウィジェット

Panelは、Bokehに基づいており、Bokehの拡張機能を使ってカスタムウィジェットを作成することも可能です。BokehのJavaScript拡張を使用することで、複雑なウィジェットをPanelに統合できます。

例3: Bokeh拡張によるカスタムスライダー

次に、Bokehの拡張機能を使って、カスタムスライダーを作成します。

from bokeh.models import Slider
from bokeh.models.callbacks import CustomJS
import panel as pn

pn.extension()

# カスタムJavaScriptコードを持つスライダーの作成
slider = Slider(start=0, end=100, value=50, step=1, title="Custom Slider")
slider.js_on_change("value", CustomJS(code="""
    console.log("Slider value: " + this.value);
"""))

# Panelにスライダーを組み込む
slider_pane = pn.pane.Bokeh(slider)

# レイアウトの表示
layout = pn.Column("## Bokeh Custom Slider", slider_pane)
layout.servable()
pn.serve()
  • Slider はBokehのスライダーウィジェットで、値が変わるたびにJavaScriptコードが実行されます。
  • CustomJS を使って、スライダーの値変更イベントを捕捉し、コンソールに値を出力しています。
  • pn.pane.Bokeh を使って、BokehウィジェットをPanelに組み込んでいます。

この方法を使うことで、Bokehの拡張機能を活用し、さらにカスタマイズされたウィジェットをPanelに追加できます。

まとめ

今回の記事では、Panelアプリにカスタムコンポーネントを組み込むさまざまな方法を紹介しました。JavaScriptやReact、Bokeh拡張を使うことで、より高度なインタラクションや独自のUIを実装することが可能です。これにより、Panelアプリケーションはより柔軟でパワフルなものとなり、特定の要件に応じたダッシュボードやWebアプリケーションを構築できるようになります。

次回は、パフォーマンス最適化とスケーリングについて解説します。お楽しみに!

コメント

タイトルとURLをコピーしました