QuickSight 埋め込み SDK でコントロール値を取得してみた
QuickSight のダッシュボードをアプリケーションに埋め込んでいる際、コントロールで現在選択している値を取得したいことがあります。
検証している中で、amazon-quicksight-embedding-sdk の onMessage で実現できることがわかったのでメモします。
具体的にやりたいことは、例えば「ALL(すべて)」が選択されていると、アプリ側で ALL を取得し、
他の値が選択されると、変更後の値を取得するといったものです。
以下検証手順を残します。
フィルターコントロールを持つ QuickSight ダッシュボードの作成
サンプルデータからビジュアルを作成
以下サンプル CSV を用意します。
地名,ポイント
沖縄,100
沖縄,200
北海道,300
北海道,400
東京,500
東京,600
上記ファイルを QuickSight へアップロードし、分析を作成します。
以下では、ビジュアルとしてテーブルを作成しています。
このままでは見た目が味気ないので、円グラフも追加してみます(任意)。
フィルターコントロールの作成
続いてコントロールを配置していきます。
まずは、パラメータを追加します。
作成したパラメータを指定してコントロールを追加します。
コントロールが追加されました。
一方でこの時点ではコントロールの値を変更してもビジュアルの表示は変わりません。
以下画像ではプルダウンから沖縄を選択していますが、グラフでは全ての都道府県が表示されています。
そのため、コントロールの値に応じてグラフが変わるようフィルターを設定します。
以下画像のようにフィルタータイプを「カスタムフィルター」とし、「パラメータを使用」にチェックを入れ、作成しておいた "prefectures" パラメータを選択します。
そうするとコントロールで「すべて」を選ぶと全ての都道府県の情報が表示され、
特定の地域(例えば沖縄)を選ぶと、以下のように沖縄のデータだけがフィルタされて表示されます。
これで、コントロールに応じてビジュアルの内容がフィルタされるフィルターコントロールを持った分析が作成できました。
ダッシュボードとして公開する
作成した分析をダッシュボードとして公開します。そして、URL の末尾に示される ダッシュボード ID を控えておきます。(後述の手順でダッシュボード ID を使用します)
ダッシュボードの埋め込み
埋め込み環境の作成
前項にて作成したダッシュボードをWebサイトに埋め込みます。
埋め込み環境(CloudFront + S3 または S3 単体)の作成方法は以下のブログを参考にしてください。
HTML ファイルの作成
埋め込み環境を作成したら、続いて、ダッシュボードを埋め込むための埋め込み URL を作成します。
CloudShell または CLI を実行できる環境で、以下コマンドを実行します。
$ aws quicksight generate-embed-url-for-registered-user --aws-account-id <アカウント ID> --session-lifetime-in-minutes 30 --user-arn <使用する QuickSight ユーザー ARN> --experience-configuration Dashboard={InitialDashboardId=<前項にてコピーしたダッシュボード ID>}
※上記コマンド実行のためのユーザー ARN がわからない場合は、list-users コマンドなどから確認してください。
上記コマンド実行後、以下のような出力結果が得られるため、"EmbedUrl" をコピーしておきます。
{
"Status": "200",
"EmbedUrl": "https://quicksightdomain/embed/12345/dashboards/67890..",
"RequestId": "7bee030e-f191-45c4-97fe-d9faf0e03713"
}
続いて、S3 に配置する HTML を以下のように作成します。これは公式ドキュメントの SDK 2.0 の内容をそのままコピーしたものです。
この HTML 内の "<YOUR_EMBED_URL>" 部分を先ほどコピーした "EmbedUrl" に置き換えます。それ以外はそのままで OK です。準備ができたら S3 にアップロードします。
hogehoge.html
<!DOCTYPE html>
<html>
<head>
<title>Dashboard Embedding Example</title>
<script src="https://unpkg.com/amazon-quicksight-embedding-sdk@2.0.0/dist/quicksight-embedding-js-sdk.min.js"></script>
<script type="text/javascript">
const embedDashboard = async() => {
const {
createEmbeddingContext,
} = QuickSightEmbedding;
const embeddingContext = await createEmbeddingContext({
onChange: (changeEvent, metadata) => {
console.log('Context received a change', changeEvent, metadata);
},
});
const frameOptions = {
url: '<YOUR_EMBED_URL>',
container: '#experience-container',
height: "700px",
width: "1000px",
onChange: (changeEvent, metadata) => {
switch (changeEvent.eventName) {
case 'FRAME_MOUNTED': {
console.log("Do something when the experience frame is mounted.");
break;
}
case 'FRAME_LOADED': {
console.log("Do something when the experience frame is loaded.");
break;
}
}
},
};
const contentOptions = {
parameters: [
{
Name: 'country',
Values: [
'United States'
],
},
{
Name: 'states',
Values: [
'California',
'Washington'
]
}
],
locale: "en-US",
sheetOptions: {
initialSheetId: '<YOUR_SHEETID>',
singleSheet: false,
emitSizeChangedEventOnSheetChange: false,
},
toolbarOptions: {
export: false,
undoRedo: false,
reset: false
},
attributionOptions: {
overlayContent: false,
},
onMessage: async (messageEvent, experienceMetadata) => {
switch (messageEvent.eventName) {
case 'CONTENT_LOADED': {
console.log("All visuals are loaded. The title of the document:", messageEvent.message.title);
break;
}
case 'ERROR_OCCURRED': {
console.log("Error occurred while rendering the experience. Error code:", messageEvent.message.errorCode);
break;
}
case 'PARAMETERS_CHANGED': {
console.log("Parameters changed. Changed parameters:", messageEvent.message.changedParameters);
break;
}
case 'SELECTED_SHEET_CHANGED': {
console.log("Selected sheet changed. Selected sheet:", messageEvent.message.selectedSheet);
break;
}
case 'SIZE_CHANGED': {
console.log("Size changed. New dimensions:", messageEvent.message);
break;
}
case 'MODAL_OPENED': {
window.scrollTo({
top: 0 // iframe top position
});
break;
}
}
},
};
const embeddedDashboardExperience = await embeddingContext.embedDashboard(frameOptions, contentOptions);
const selectCountryElement = document.getElementById('country');
selectCountryElement.addEventListener('change', (event) => {
embeddedDashboardExperience.setParameters([
{
Name: 'country',
Values: event.target.value
}
]);
});
};
</script>
</head>
<body onload="embedDashboard()">
<span>
<label for="country">Country</label>
<select id="country" name="country">
<option value="United States">United States</option>
<option value="Mexico">Mexico</option>
<option value="Canada">Canada</option>
</select>
</span>
<div id="experience-container"></div>
</body>
</html>
なお、この後動作確認しますが、上記 HTML コードでは、既にコントロールの値を取得するための onMessage 関数が含まれたものになっています。
onMessage 関数では、コントロールのパラメータが変更された際、messageEvent.eventName 変数に 'PARAMETERS_CHANGED' として通知されます。
そしてその変更後の値は messageEvent.message.changedParameters の中から取得が可能です。
以下が、onMessage のドキュメントの記述になります。パラメータが変更されたときに受信されると記載があります。
onMessage: EventListener (optional)
The eventNames the dashboard experience receives
...
PARAMETERS_CHANGED: Received when the parameters in Amazon QuickSight dashboard changes.
動作確認
前項までで準備ができたので、動作確認をします。
前提として、先ほどの HTML ファイルを S3 にアップロードし、Web ブラウザ(Chrome のシークレットウィンドウを利用)からアクセスすると以下のようにダッシュボードが表示されます。
本ダッシュボードでは、プルダウンから各項目を選択できる形になっています。
ここで、"ALL" を選択すると、以下のように都道府県全ての情報を含むグラフが表示され、Chrome の開発者ツールから見ると、選択された "ALL" が取得できていることがわかります。
別項目を選んでみます。別項目を選んだ場合はその項目のみのグラフが表示され、かつアプリ側でも変更後の値を取得することができています。
終わりに
今回は、埋め込み時にコントロールの値を取得する関数 onMessage の動作確認をしてみました。
amazon-quicksight-embedding-sdk を使えば割と簡単にコントロールの現在値を取得できることがわかりました。GitHub を見ると他の機能もたくさんあるようなので、あれこれ触ってみたくなりました。
本ブログがお役に立てば幸いです。
参考文献