以前にグラフ問合せを扱った記事を書いたことがありますが、問い合わせの結果をレポート、つまり表形式で印刷していました。それではイマイチなので、APEXでCytoscape.jsを使う方法を確認してみました。
Cytoscape.jsのページに記載されているGetting startedをAPEXのアプリケーションとして実装してみました。Getting Startedをそのまま埋め込むのではなく、アプリケーションのサンプルとして役立つように以下の実装を加えています。
- elementsとstyleは静的なJSONファイルではなく、サーバー側で生成した値を使う。
- ページ・ロード時にグラフを描画するのではなく、ブラウザのイベントより(今回はボタンの押下)生成する。
簡単なアプリケーションですが、以下に実装を紹介します。
最初に空のアプリケーションを作成します。実装はホーム・ページに行います。
ページ・プロパティのJavaScriptのファイルURLとして、Cytoscape.jsを指定します。バージョンなどは変わるため、実装時はCytoscape.jsのホームページよりリンクを取得してください。
https://unpkg.com/cytoscape@3.23.0/dist/cytoscape.min.js
グラフを描画する領域を作成します。
新規にリージョンを作成します。
作成したリージョンの識別のタイトルはCytoscape、タイプは静的コンテンツとします。ソースのHTMLコードとして以下を記述します。
<div id="cy"></div>
装飾は不要なので、外観のテンプレートとしてBlank with Attributesを選択します。
HTMLコードとして記述したid="cy"のDIV要素にCytoscapeによるグラフが描画されます。描画領域をCSSで指定します。
ページ・プロパティのCSSのインラインに以下を記述します。
#cy {
width: 300px;
height: 300px;
display: block;
}
declare | |
l_response clob; | |
l_response_json json_object_t; | |
l_data_array json_array_t; | |
l_data json_object_t; | |
l_style_array json_array_t; | |
l_style json_object_t; | |
begin | |
/* elementsの作成 */ | |
l_data_array := json_array_t(); | |
l_data := json_object_t(); | |
l_data.put('data', json_object_t( | |
json_object( | |
'id' value 'a' | |
))); | |
l_data_array.append(l_data); | |
l_data := json_object_t(); | |
l_data.put('data', json_object_t( | |
json_object( | |
'id' value 'b' | |
))); | |
l_data_array.append(l_data); | |
l_data := json_object_t(); | |
l_data.put('data', json_object_t( | |
json_object( | |
'id' value 'ab' | |
,'source' value 'a' | |
,'target' value 'b' | |
))); | |
l_data_array.append(l_data); | |
/* sytleの作成 */ | |
l_style_array := json_array_t(); | |
l_style := json_object_t(); | |
l_style.put('style', json_object_t( | |
json_object( | |
'background-color' value '#666' | |
,'label' value 'data(id)' | |
))); | |
l_style_array.append(l_style); | |
l_style := json_object_t(); | |
l_style.put('selector','node'); | |
l_style.put('style', json_object_t( | |
json_object( | |
'background-color' value '#666' | |
,'label' value 'data(id)' | |
))); | |
l_style_array.append(l_style); | |
l_style := json_object_t(); | |
l_style.put('selector','edge'); | |
l_style.put('style', json_object_t( | |
json_object( | |
'width' value 3 | |
,'line-color' value '#ccc' | |
,'target-arrow-color' value '#ccc' | |
,'target-arrow-shape' value 'triangle' | |
,'curve-style' value 'bezier' | |
))); | |
l_style_array.append(l_style); | |
/* 応答となるJSONを生成 */ | |
l_response_json := json_object_t(); | |
l_response_json.put('elements', l_data_array); | |
l_response_json.put('style', l_style_array); | |
l_response := l_response_json.to_clob(); | |
apex_debug.info(l_response); | |
htp.p(l_response); | |
end; |
var cy; | |
const RENDER_CY = { | |
name: "render-cy", | |
action: (event, element, args) => { | |
let result = apex.server.process("GET_DATA", { | |
x01: "get_data" | |
}); | |
result.done( (data) => { | |
cy = cytoscape({ | |
container: document.getElementById('cy'), // container to render in | |
elements: data.elements, | |
style: data.style, | |
layout: { | |
name: 'grid', | |
rows: 1 | |
} | |
}) | |
}); | |
} | |
}; |