Skip to content

Instantly share code, notes, and snippets.

@altavir
Created September 14, 2020 14:13
Show Gist options
  • Save altavir/18f6a8d77dc538f95ddcff51b6532861 to your computer and use it in GitHub Desktop.
Save altavir/18f6a8d77dc538f95ddcff51b6532861 to your computer and use it in GitHub Desktop.
Drawing images in plotly.kt using unsupported feature.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<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",
" if(window.plotlyCallQueue){\n",
" window.plotlyCallQueue.forEach(function(theCall) {theCall();});\n",
" window.plotlyCallQueue = [];\n",
" }\n",
" }\n",
"})();</script>\n",
"<script type=\"text/javascript\" src=\"https://cdn.plot.ly/plotly-1.54.6.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": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
" <div id=\"kscience.plotly.Plot@3243d4ca\">\n",
" <script>(function (){\n",
" let theCall = function(){\n",
" makePlot(\n",
" 'kscience.plotly.Plot@3243d4ca',\n",
" [{\"x\":[1,2,3],\"y\":[1,2,3]}],\n",
" {\"images\":[{\"sizex\":0.2,\"yref\":\"paper\",\"xref\":\"paper\",\"xanchor\":\"right\",\"@index\":\"0\",\"x\":0,\"y\":1,\"yanchor\":\"bottom\",\"source\":\"https://images.plot.ly/language-icons/api-home/python-logo.png\",\"sizey\":0.2},{\"sizex\":1,\"yref\":\"y\",\"xref\":\"x\",\"xanchor\":\"right\",\"@index\":\"1\",\"x\":1.5,\"y\":2,\"yanchor\":\"bottom\",\"source\":\"https://images.plot.ly/language-icons/api-home/js-logo.png\",\"sizey\":1}]},\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",
" } else {\n",
" theCall();\n",
" }\n",
"}());</script>\n",
" </div>\n",
"</div>\n"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Plotly.plot {\n",
" trace{\n",
" x(1,2,3)\n",
" y(1,2,3)\n",
" }\n",
" layout{\n",
" config[\"images\"] = listOf(\n",
" Meta{\n",
" \"source\" put \"https://images.plot.ly/language-icons/api-home/python-logo.png\"\n",
" \"xref\" put \"paper\"\n",
" \"yref\" put \"paper\"\n",
" \"x\" put 0\n",
" \"y\" put 1\n",
" \"sizex\" put 0.2\n",
" \"sizey\" put 0.2\n",
" \"xanchor\" put \"right\"\n",
" \"yanchor\" put \"bottom\"\n",
" },\n",
" Meta{\n",
" \"source\" put \"https://images.plot.ly/language-icons/api-home/js-logo.png\"\n",
" \"xref\" put \"x\"\n",
" \"yref\" put \"y\"\n",
" \"x\" put 1.5\n",
" \"y\" put 2\n",
" \"sizex\" put 1\n",
" \"sizey\" put 1\n",
" \"xanchor\" put \"right\"\n",
" \"yanchor\" put \"bottom\"\n",
" }\n",
" )\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"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"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment