こんにちは、JS2IIUです。今回はアイキャッチ画像の文字がはみ出てしまいました。今回もよろしくお願いします。
はじめに
Panelは、豊富なUIコンポーネントを提供していますが、時にはカスタムウィジェットや独自のインタラクションが必要になることもあります。本記事では、Panelの拡張方法について解説します。具体的には、ReactやJavaScriptを使ってカスタムコンポーネントを作成し、それをPanelアプリに組み込む方法を紹介します。これにより、標準のUIコンポーネントを超えた柔軟な機能を実装できます。
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:
npx create-react-app my-app
Windows:
こちらの記事を参照して下さい。
手順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アプリケーションを構築できるようになります。
次回は、パフォーマンス最適化とスケーリングについて解説します。お楽しみに!

