335 lines
12 KiB
Plaintext
335 lines
12 KiB
Plaintext
|
{
|
||
|
"cells": [
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": 1,
|
||
|
"metadata": {},
|
||
|
"outputs": [
|
||
|
{
|
||
|
"name": "stdout",
|
||
|
"output_type": "stream",
|
||
|
"text": [
|
||
|
"21:08:36.601 [DefaultDispatcher-worker-1] INFO ktor.application - No ktor.deployment.watch patterns specified, automatic reload is not active\n",
|
||
|
"21:08:36.645 [DefaultDispatcher-worker-1] INFO ktor.application - Responding at http://0.0.0.0:8882\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"data": {
|
||
|
"text/html": [
|
||
|
"<div id=\"plotly-load-scripts\"></div>\n",
|
||
|
"<script type=\"text/javascript\">(function() {\n",
|
||
|
" console.log(\"Starting up plotly script loader\");\n",
|
||
|
" //initialize LaTeX for Jupyter\n",
|
||
|
" window.PlotlyConfig = {MathJaxConfig: 'local'};\n",
|
||
|
"\n",
|
||
|
" window.startupPlotly = function (){\n",
|
||
|
" if (window.MathJax){ \n",
|
||
|
" MathJax.Hub.Config({\n",
|
||
|
" SVG: {\n",
|
||
|
" font: \"STIX-Web\"\n",
|
||
|
" }\n",
|
||
|
" });\n",
|
||
|
" } \n",
|
||
|
" console.info(\"Calling deferred operations in Plotly queue.\")\n",
|
||
|
" window.plotlyCallQueue.forEach(function(theCall) {theCall();});\n",
|
||
|
" window.plotlyCallQueue = []; \n",
|
||
|
" }\n",
|
||
|
"})();</script>\n",
|
||
|
"<script type=\"text/javascript\" src=\"//localhost:8882/js/plotly.min.js\"></script>\n",
|
||
|
"<script type=\"text/javascript\">/**\r\n",
|
||
|
" * Use existing plotly or load it from the CDN if it is not available\r\n",
|
||
|
" * @param action\r\n",
|
||
|
" */\r\n",
|
||
|
"function withPlotly(action) {\r\n",
|
||
|
" if (typeof Plotly !== \"undefined\") {\r\n",
|
||
|
" action(Plotly);\r\n",
|
||
|
" } else if (typeof window.promiseOfPlotly !== \"undefined\") {\r\n",
|
||
|
" window.promiseOfPlotly.then(plotly => action(plotly));\r\n",
|
||
|
" } else {\r\n",
|
||
|
" console.warn(\"Plotly not defined. Loading the script from CDN\")\r\n",
|
||
|
" window.promiseOfPlotly = new Promise((accept, reject) => {\r\n",
|
||
|
" let plotlyLoaderScript = document.createElement(\"script\");\r\n",
|
||
|
" plotlyLoaderScript.src = \"https://cdnjs.cloudflare.com/ajax/libs/plotly.js/1.54.6/plotly.min.js\";\r\n",
|
||
|
" plotlyLoaderScript.type = 'text/javascript';\r\n",
|
||
|
" plotlyLoaderScript.onload = () => {\r\n",
|
||
|
" accept(Plotly);\r\n",
|
||
|
" }\r\n",
|
||
|
" plotlyLoaderScript.onerror = (error) => {\r\n",
|
||
|
" console.error(error);\r\n",
|
||
|
" reject(error)\r\n",
|
||
|
" }\r\n",
|
||
|
" document.head.appendChild(plotlyLoaderScript);\r\n",
|
||
|
" });\r\n",
|
||
|
" }\r\n",
|
||
|
"}\r\n",
|
||
|
"\r\n",
|
||
|
"/**\r\n",
|
||
|
" * Request and parse json from given address\r\n",
|
||
|
" * @param url {URL}\r\n",
|
||
|
" * @param callback\r\n",
|
||
|
" * @return Promise<Json>\r\n",
|
||
|
" */\r\n",
|
||
|
"function getJSON(url, callback) {\r\n",
|
||
|
"\r\n",
|
||
|
" function handleErrors(response) {\r\n",
|
||
|
" if (!response.ok) {\r\n",
|
||
|
" throw Error(response.statusText);\r\n",
|
||
|
" }\r\n",
|
||
|
" return response;\r\n",
|
||
|
" }\r\n",
|
||
|
"\r\n",
|
||
|
" try {\r\n",
|
||
|
" fetch(url, {\r\n",
|
||
|
" method: 'GET',\r\n",
|
||
|
" headers: {\r\n",
|
||
|
" Accept: 'application/json',\r\n",
|
||
|
" }\r\n",
|
||
|
" })\r\n",
|
||
|
" .then(handleErrors)\r\n",
|
||
|
" .then(response => response.json())\r\n",
|
||
|
" .then(json => callback(json))\r\n",
|
||
|
" .catch(error => console.log(error));\r\n",
|
||
|
" } catch (e) {\r\n",
|
||
|
" alert(\"Fetch of plot data failed with error: \" + e)\r\n",
|
||
|
" }\r\n",
|
||
|
"}\r\n",
|
||
|
"\r\n",
|
||
|
"/**\r\n",
|
||
|
" * Safe call for Plotly.newPlot\r\n",
|
||
|
" * @param id\r\n",
|
||
|
" * @param data\r\n",
|
||
|
" * @param layout\r\n",
|
||
|
" * @param config\r\n",
|
||
|
" */\r\n",
|
||
|
"function makePlot(id, data, layout, config) {\r\n",
|
||
|
" withPlotly(plotly => plotly.newPlot(id, data, layout, config))\r\n",
|
||
|
"}\r\n",
|
||
|
"\r\n",
|
||
|
"/**\r\n",
|
||
|
" * Create a plot taking data from given url\r\n",
|
||
|
" * @param id {string} element id for plot\r\n",
|
||
|
" * @param from {URL} json server url\r\n",
|
||
|
" * @param config {object} plotly configuration\r\n",
|
||
|
" * @return {JSON}\r\n",
|
||
|
" */\r\n",
|
||
|
"function createPlotFrom(id, from, config = {}) {\r\n",
|
||
|
" getJSON(from, json => withPlotly(plotly => {\r\n",
|
||
|
" plotly.newPlot(id, json.data, json.layout, config)\r\n",
|
||
|
" }));\r\n",
|
||
|
"}\r\n",
|
||
|
"\r\n",
|
||
|
"/**\r\n",
|
||
|
" * Update a plot taking data from given url\r\n",
|
||
|
" * @param id {string} element id for plot\r\n",
|
||
|
" * @param from {URL} json server url\r\n",
|
||
|
" * @return {JSON}\r\n",
|
||
|
" */\r\n",
|
||
|
"function updatePlotFrom(id, from) {\r\n",
|
||
|
" getJSON(from, json => withPlotly(plotly => plotly.react(id, json.data, json.layout)));\r\n",
|
||
|
"}\r\n",
|
||
|
"\r\n",
|
||
|
"/**\r\n",
|
||
|
" * Start pull updates with regular requests from client side\r\n",
|
||
|
" * @param id {string}\r\n",
|
||
|
" * @param from\r\n",
|
||
|
" * @param millis\r\n",
|
||
|
" */\r\n",
|
||
|
"function startPull(id, from, millis) {\r\n",
|
||
|
" let action = function () {\r\n",
|
||
|
" updatePlotFrom(id, from)\r\n",
|
||
|
" };\r\n",
|
||
|
" window.setInterval(action, millis)\r\n",
|
||
|
"}\r\n",
|
||
|
"\r\n",
|
||
|
"/**\r\n",
|
||
|
" * Start push updates via websocket\r\n",
|
||
|
" * @param id {string} element id for plot\r\n",
|
||
|
" * @param ws {URL} a websocket address\r\n",
|
||
|
" */\r\n",
|
||
|
"function startPush(id, ws) {\r\n",
|
||
|
" let socket = new WebSocket(ws);\r\n",
|
||
|
"\r\n",
|
||
|
" socket.onopen = function () {\r\n",
|
||
|
" console.log(\"[Plotly.kt] A connection for plot with id = \" + id + \" with server established on \" + ws);\r\n",
|
||
|
" };\r\n",
|
||
|
"\r\n",
|
||
|
" socket.onclose = function (event) {\r\n",
|
||
|
" if (event.wasClean) {\r\n",
|
||
|
" console.log(\"The connection with server is closed\");\r\n",
|
||
|
" } else {\r\n",
|
||
|
" console.log(\"The connection with server is broken\"); // Server process is dead\r\n",
|
||
|
" }\r\n",
|
||
|
" console.log('Code: ' + event.code + ' case: ' + event.reason);\r\n",
|
||
|
" };\r\n",
|
||
|
"\r\n",
|
||
|
" socket.onerror = function (error) {\r\n",
|
||
|
" console.error(\"Ploty push update error: \" + error.message);\r\n",
|
||
|
" socket.close()\r\n",
|
||
|
" };\r\n",
|
||
|
"\r\n",
|
||
|
" socket.onmessage = function (event) {\r\n",
|
||
|
" //console.log('got message: ' + event.data);\r\n",
|
||
|
" let json = JSON.parse(event.data);\r\n",
|
||
|
" //TODO check if plotly is initialized in a cell\r\n",
|
||
|
" if (json.plotId === id) {\r\n",
|
||
|
" if (json.contentType === \"layout\") {\r\n",
|
||
|
" withPlotly(plotly => plotly.relayout(id, json.content));\r\n",
|
||
|
" } else if (json.contentType === \"trace\") {\r\n",
|
||
|
" let content = json.content;\r\n",
|
||
|
" //This is done to satisfy plotly requirements of arrays-in-arrays for data\r\n",
|
||
|
" if (content.hasOwnProperty('x')) {\r\n",
|
||
|
" content.x = [content.x];\r\n",
|
||
|
" }\r\n",
|
||
|
" if (content.hasOwnProperty('y')) {\r\n",
|
||
|
" content.y = [content.y];\r\n",
|
||
|
" }\r\n",
|
||
|
" if (content.hasOwnProperty('z')) {\r\n",
|
||
|
" content.z = [content.z];\r\n",
|
||
|
" }\r\n",
|
||
|
" withPlotly(plotly => plotly.restyle(id, content, json['trace']));\r\n",
|
||
|
" }\r\n",
|
||
|
" }\r\n",
|
||
|
" };\r\n",
|
||
|
"\r\n",
|
||
|
" //gracefully close socket just in case\r\n",
|
||
|
" window.onbeforeunload = function () {\r\n",
|
||
|
" console.log(\"Gracefully closing socket\");\r\n",
|
||
|
" socket.onclose = function () {\r\n",
|
||
|
" }; // disable onclose handler first\r\n",
|
||
|
" socket.close();\r\n",
|
||
|
" };\r\n",
|
||
|
"}\r\n",
|
||
|
"\r\n",
|
||
|
"\r\n",
|
||
|
"window.startupPlotly()</script>\n"
|
||
|
]
|
||
|
},
|
||
|
"metadata": {},
|
||
|
"output_type": "display_data"
|
||
|
}
|
||
|
],
|
||
|
"source": [
|
||
|
"%use plotly"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": 2,
|
||
|
"metadata": {
|
||
|
"ExecuteTime": {
|
||
|
"end_time": "2020-08-07T11:08+0300",
|
||
|
"start_time": "2020-08-07T11:08+0300"
|
||
|
}
|
||
|
},
|
||
|
"outputs": [
|
||
|
{
|
||
|
"data": {
|
||
|
"text/html": [
|
||
|
"<div>\n",
|
||
|
" <div id=\"scientifik.plotly.Plot@122c8b64\">\n",
|
||
|
" <script>\n",
|
||
|
"let theCall = function(){\n",
|
||
|
" makePlot(\n",
|
||
|
" 'scientifik.plotly.Plot@122c8b64',\n",
|
||
|
" [{\"x\":[2,3,4,5],\"y\":[10,15,13,17],\"type\":\"scatter\"}],\n",
|
||
|
" {\"annotations\":[{\"@index\":\"0\",\"x\":2,\"y\":10,\"text\":\"$\\\\alpha$\",\"font\":{\"size\":18}},{\"@index\":\"1\",\"x\":5,\"y\":17,\"text\":\"$\\\\Omega$\",\"font\":{\"size\":18}}],\"title\":{\"text\":\"$\\\\text{Plot with annotations } \\\\alpha~and~\\\\Omega$\"}},\n",
|
||
|
" {\"responsive\":true}\n",
|
||
|
" ); \n",
|
||
|
"};\n",
|
||
|
"\n",
|
||
|
"if(typeof Plotly === 'undefined'){\n",
|
||
|
" if(!window.plotlyCallQueue) {\n",
|
||
|
" window.plotlyCallQueue = [];\n",
|
||
|
" } \n",
|
||
|
" window.plotlyCallQueue.push(theCall)\n",
|
||
|
" window.plotlyCall(theCall);\n",
|
||
|
"} else {\n",
|
||
|
" theCall();\n",
|
||
|
"}\n",
|
||
|
"</script>\n",
|
||
|
" <script id=\"scientifik.plotly.Plot@122c8b64-push\">\n",
|
||
|
" \n",
|
||
|
" startPush('scientifik.plotly.Plot@122c8b64', 'ws://localhost:8882/ws/scientifik.plotly.Plot@122c8b64');\n",
|
||
|
" \n",
|
||
|
" </script>\n",
|
||
|
" </div>\n",
|
||
|
"</div>\n"
|
||
|
]
|
||
|
},
|
||
|
"execution_count": 2,
|
||
|
"metadata": {},
|
||
|
"output_type": "execute_result"
|
||
|
}
|
||
|
],
|
||
|
"source": [
|
||
|
"Plotly.plot {\n",
|
||
|
" scatter {\n",
|
||
|
" x(2, 3, 4, 5)\n",
|
||
|
" y(10, 15, 13, 17)\n",
|
||
|
" }\n",
|
||
|
"\n",
|
||
|
" text {\n",
|
||
|
" position(2, 10)\n",
|
||
|
" font {\n",
|
||
|
" size = 18\n",
|
||
|
" }\n",
|
||
|
" text = \"\\$\\\\alpha\\$\"\n",
|
||
|
" }\n",
|
||
|
"\n",
|
||
|
" text {\n",
|
||
|
" position(5, 17)\n",
|
||
|
" font {\n",
|
||
|
" size = 18\n",
|
||
|
" }\n",
|
||
|
" text = \"\\$\\\\Omega\\$\"\n",
|
||
|
" }\n",
|
||
|
"\n",
|
||
|
" layout {\n",
|
||
|
" title {\n",
|
||
|
" text = \"\\$\\\\text{Plot with annotations } \\\\alpha~and~\\\\Omega\\$\"\n",
|
||
|
" }\n",
|
||
|
" }\n",
|
||
|
"}"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": null,
|
||
|
"metadata": {},
|
||
|
"outputs": [],
|
||
|
"source": []
|
||
|
}
|
||
|
],
|
||
|
"metadata": {
|
||
|
"hide_input": false,
|
||
|
"kernelspec": {
|
||
|
"display_name": "Kotlin",
|
||
|
"language": "kotlin",
|
||
|
"name": "kotlin"
|
||
|
},
|
||
|
"language_info": {
|
||
|
"codemirror_mode": "text/x-kotlin",
|
||
|
"file_extension": ".kt",
|
||
|
"mimetype": "text/x-kotlin",
|
||
|
"name": "kotlin",
|
||
|
"pygments_lexer": "kotlin",
|
||
|
"version": "1.4.20-dev-2342"
|
||
|
},
|
||
|
"toc": {
|
||
|
"base_numbering": 1,
|
||
|
"nav_menu": {},
|
||
|
"number_sections": false,
|
||
|
"sideBar": false,
|
||
|
"skip_h1_title": false,
|
||
|
"title_cell": "Table of Contents",
|
||
|
"title_sidebar": "Contents",
|
||
|
"toc_cell": false,
|
||
|
"toc_position": {},
|
||
|
"toc_section_display": false,
|
||
|
"toc_window_display": false
|
||
|
}
|
||
|
},
|
||
|
"nbformat": 4,
|
||
|
"nbformat_minor": 4
|
||
|
}
|