<commit_before>{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import requests\n",
    "import ipywidgets as widgets\n",
    "import json\n",
    "import time\n",
    "import os\n",
    "from IPython.display import display, HTML\n",
    "from traitlets import Int, Unicode, observe"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<link rel=\"stylesheet\" type=\"text/css\" href=\"//igv.org/web/release/1.0.6/igv-1.0.6.css\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "display(HTML('<link rel=\"stylesheet\" type=\"text/css\" href=\"//igv.org/web/release/1.0.6/igv-1.0.6.css\">'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class TabsWidget(widgets.DOMWidget):\n",
    "    \n",
    "    _view_name = Unicode('TabsView').tag(sync=True)\n",
    "    _view_module = Unicode('tabsDemo').tag(sync=True)\n",
    "    frameHeight = Int(300).tag(sync=True)\n",
    "    _chromLocString = \"chr1:0-0\";\n",
    "    _rawMessage = \"\";\n",
    "    _incomingMessage = {};\n",
    "    msgFromKernel = Unicode(\"{}\").tag(sync=True)\n",
    "    msgFromBrowser = Unicode(\"{}\").tag(sync=True)\n",
    "    status = \"initial status message\\n\"\n",
    "\n",
    "       # ensure that any ensuing message is seen as novel in the browser\n",
    "       # the message (a json-ified string) is a mutable traitlet.  the browser only sees \n",
    "       # the message if it changes\n",
    "    def _sendResetMessageToBrowser(self):  \n",
    "       self.msgFromKernel = json.dumps({\"cmd\": \"cleanSlate\", \"status\": \"nop\", \"callback\": \"\", \"payload\": \"\"});\n",
    "\n",
    "    def setHeight(self, height):\n",
    "       print(\"setHeight(%d) \"% height)\n",
    "       self.frameHeight = height\n",
    "        \n",
    "    def getChromLocString(self):\n",
    "        return self._chromLocString\n",
    "    \n",
    "    def ping(self):\n",
    "        self._sendResetMessageToBrowser()\n",
    "        self.msgFromKernel = json.dumps({\"cmd\": \"ping\", \"status\": \"request\", \"callback\": \"\", \"payload\": \"\"});\n",
    "\n",
    "    def deleteGraph(self):\n",
    "      self._sendResetMessageToBrowser()\n",
    "      self.msgFromKernel = json.dumps({\"cmd\": \"deleteGraph\", \"status\": \"request\", \"callback\": \"\", \"payload\": \"\"});\n",
    "\n",
    "    def addGraph(self, gjson):\n",
    "      self._sendResetMessageToBrowser();\n",
    "      self.msgFromKernel = json.dumps({\"cmd\": \"addGraph\", \"status\": \"request\",\n",
    "                                       \"callback\": \"\",    \"payload\": gjson});\n",
    "    def fitSelected(self, margin=50):\n",
    "      self._sendResetMessageToBrowser();\n",
    "      self.status += \"entering fitSelected (%d)\\n\" % margin\n",
    "      self.msgFromKernel = json.dumps({\"cmd\": \"fitSelected\", \"status\": \"request\", \"callback\": \"\", \"payload\": margin});\n",
    "        \n",
    "    def fit(self, margin=50):\n",
    "      self._sendResetMessageToBrowser();\n",
    "      self.status += \"entering fit (%d)\\n\" % margin\n",
    "      self.msgFromKernel = json.dumps({\"cmd\": \"fit\", \"status\": \"request\", \"callback\": \"\", \"payload\": margin});\n",
    "\n",
    "\n",
    "    def availableLayouts(self):\n",
    "      self._sendResetMessageToBrowser();\n",
    "\n",
    "      return([\"grid\", \"null\", \"random\", \"cose\", \"circle\", \"concentric\", \"breadthfirst\"]);\n",
    "\n",
    "    def layout(self, name):\n",
    "      self._sendResetMessageToBrowser();\n",
    "      self.msgFromKernel = json.dumps({\"cmd\": \"layout\", \"status\": \"request\", \"callback\": \"\", \"payload\": name});\n",
    "\n",
    "    def tfGridLayout(self):\n",
    "      self._sendResetMessageToBrowser();\n",
    "      self.msgFromKernel = json.dumps({\"cmd\": \"tfGridLayout\", \"status\": \"request\", \"callback\": \"\", \"payload\": \"\"});\n",
    "\n",
    "    def selectedNodeGridLayout(self, name):\n",
    "      self._sendResetMessageToBrowser();\n",
    "      self.msgFromKernel = json.dumps({\"cmd\": \"selectedNodeGridLayout\", \"status\": \"request\", \"callback\": \"\", \"payload\": \"\"});\n",
    "\n",
    "\n",
    "    def loadNetworkStyleFile(self, filename):\n",
    "      if(not os.path.isfile(filename)):\n",
    "        print(\"file '%s' not found\" % filename)\n",
    "        return;\n",
    "      self._sendResetMessageToBrowser();\n",
    "      self.msgFromKernel = json.dumps({\"cmd\": \"loadNetworkStyleFile\", \"status\": \"request\", \"callback\": \"\", \n",
    "                                       \"payload\": filename});\n",
    "        \n",
    "\n",
    "    @observe('msgFromBrowser')\n",
    "    def msg_arrived(self, change):\n",
    "       #self.status += \"msgFromBrowser has arrived: %f\\n\" % time.time()\n",
    "       self._rawMessage = change['new']\n",
    "       #self.status += \"rawMessage: %s\\n\" % self._rawMessage\n",
    "       self._incomingMessage = json.loads(self._rawMessage)\n",
    "       cmd = self._incomingMessage[\"cmd\"]\n",
    "       #self.status += \"cmd: %s\\n\"  % cmd\n",
    "       if(cmd == \"updateChromLocString\"):\n",
    "          self._chromLocString = self._incomingMessage[\"payload\"]\n",
    "       else:\n",
    "         self.status += \"unrecognized cmd: '%s'\" % cmd\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<style>\n",
       "    div#notebook-container    { width: 97%; }\n",
       "    div#menubar-container     { width: 65%; }\n",
       "    div#maintoolbar-container { width: 99%; }\n",
       "</style>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "display(HTML(data=\"\"\"\n",
    "<style>\n",
    "    div#notebook-container    { width: 97%; }\n",
    "    div#menubar-container     { width: 65%; }\n",
    "    div#maintoolbar-container { width: 99%; }\n",
    "</style>\n",
    "\"\"\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "\"use strict\"\n",
       "require.config({\n",
       "    shim: {'bootstrap': {'deps' :['jquery']},\n",
       "           'igv':       {'deps' :['jquery', 'jquery-ui', 'bootstrap']}\n",
       "           },\n",
       "\n",
       "    paths: {'jquery'    :   'http://code.jquery.com/jquery-1.12.4.min',\n",
       "            'jquery-ui' :   'http://code.jquery.com/ui/1.12.1/jquery-ui.min',\n",
       "            'cytoscape' :   'http://cytoscape.github.io/cytoscape.js/api/cytoscape.js-latest/cytoscape',\n",
       "            //'cytoscape' :   'http://localhost:8099/js/cytoscape-2.7.10',\n",
       "            'bootstrap' :   'http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min',\n",
       "            'igv'       :   'http://igv.org/web/release/1.0.6/igv-1.0.6'\n",
       "           }\n",
       "      });\n",
       "\n",
       "require.undef('tabsDemo')\n",
       "\n",
       "define('tabsDemo', [\"jupyter-js-widgets\", \"jquery\", \"jquery-ui\", \"cytoscape\", \"igv\"], \n",
       "       function(widgets, $, ui, cytoscape, igv) {\n",
       "    \n",
       "    var TabsView = widgets.DOMWidgetView.extend({\n",
       "\n",
       "        initialize: function() {\n",
       "           this.options = {}\n",
       "           this.chromLocString = \"\";\n",
       "           console.log(\"constructing TabsView\");\n",
       "           this.frameHeight = \"800px\";\n",
       "           window.cyInitialized = false;\n",
       "           },\n",
       "\n",
       "        resizeHandler: function(){\n",
       "           console.log(\"TabsView resizeHandler\")            \n",
       "           },\n",
       "        \n",
       "        createMasterTabsDiv: function(){\n",
       "           var masterTabsDiv = $(\"<div id='masterTabsDiv' style='border:1px solid gray; height: 1200px; width: 97%'></div>\");\n",
       "           var list = $(\"<ul/>\");\n",
       "           list.append(\"<li><a href='#tab-2'>igv</a></li>\");\n",
       "           list.append(\"<li><a href='#tab-1'>cytoscape</a></li>\");\n",
       "           list.append(\"<li><a href='#tab-3'>three</a></li>\");\n",
       "           masterTabsDiv.append(list);\n",
       "\n",
       "           var tab2 = $(\"<div id='tab-1'></div>\");\n",
       "            \n",
       "           tab2.append(\"<div id='cyOuterDiv' style='border:1px solid red; height:1000px;'>\" +\n",
       "                       \"<div id='cyMenubarDiv' style='background-color: lightgray; height:20px'>\" + \n",
       "                       \"<button id='cyFitButton'>Fit</button>\" +\n",
       "                       \"<button id='cySFNButton'>SFN</button>\" +\n",
       "                       \"<button id='cyHideUnselectedButton'>Hide Unselected</button>\" +\n",
       "                       \"<button id='cyShowAllButton'>Show All</button>\" +\n",
       "                       \"</div>\" +\n",
       "                       \"<div id='cyDiv' style='background-color: white; height: 960x'></div> </div>\");\n",
       "\n",
       "           var tab1 = $(\"<div id='tab-2'></div>\");\n",
       "           tab1.append(\"<div id='igvDiv' style='border:1px solid green; height:1000px;'></div>\");\n",
       "            \n",
       "           var tab3 = $(\"<div id='tab-3'>contents 3</div>\");\n",
       "            \n",
       "           masterTabsDiv.append(tab1);\n",
       "           masterTabsDiv.append(tab2);\n",
       "           masterTabsDiv.append(tab3); \n",
       "           return(masterTabsDiv);\n",
       "           },\n",
       "         \n",
       "        getCyOptions: function(){\n",
       "           var value = {container: $(\"#cyDiv\"), \n",
       "                                      elements: {nodes: [{data: {id:'a'}}],\n",
       "                                                 edges: [{data:{source:'a', target:'a'}}]},\n",
       "                                      style: cytoscape.stylesheet()\n",
       "                                        .selector('node').style({'background-color': '#d22',\n",
       "                                                                 'label': 'data(id)',\n",
       "                                                                 'text-valign': 'center',\n",
       "                                                                 'text-halign': 'center',\n",
       "                                                                 'border-width': 1})\n",
       "                                         .selector('edge').style({'line-color': 'black',\n",
       "                                                                  'target-arrow-shape': 'triangle',\n",
       "                                                                  'target-arrow-color': 'black',\n",
       "                                                                  'curve-style': 'bezier'})\n",
       "                       };\n",
       "            return(value);\n",
       "            }, // getCyOptions\n",
       "        \n",
       "        \n",
       "        getIgvOptions: function(){\n",
       "           var igvOptionsLocal = {locus: \"7:101,165,560-101,165,630\", // 5:88,621,548-88,999,827\",\n",
       "             reference: {id: \"geneSymbols_hg38\",\n",
       "                fastaURL: \"http://localhost/data/genomes/human_g1k_v37_decoy.fasta\",\n",
       "                 cytobandURL: \"http://localhost/data/annotations/b37_cytoband.txt\"\n",
       "                 },\n",
       "                tracks: [\n",
       "                  {name: 'Gencode v24',\n",
       "                   url: \"http://localhost://data/hg38/gencode.v24.annotation.sorted.gtf.gz\",\n",
       "                  indexURL: \"http://localhost://data/hg38/gencode.v24.annotation.sorted.gtf.gz.tbi\",\n",
       "                  format: 'gtf',\n",
       "                  visibilityWindow: 2000000,\n",
       "                  displayMode: 'EXPANDED'\n",
       "                  },\n",
       "                 {name: 'geneSymbols_hg38',\n",
       "                  url: 'http://localhost/data/hg38/geneSymbolSearch.bed',\n",
       "                  indexed: false,\n",
       "                  searchable: true,\n",
       "                  //visibilityWindow: 5000000,\n",
       "                  displayMode: 'COLLAPSED',\n",
       "                  color: \"#448844\"\n",
       "                  },\n",
       "                 {name: \"igap gwas\",\n",
       "                  url: 'http://localhost/data/hg38/variants/igap.bed',\n",
       "                  indexed: false,\n",
       "                  searchable: true,\n",
       "                  //visibilityWindow: 5000000,\n",
       "                  displayMode: 'EXPANDED',\n",
       "                  color: \"#884444\"\n",
       "                  }\n",
       "                  ]\n",
       "              }; // igvOptionsLocal\n",
       "             return(igvOptionsLocal);\n",
       "           }, // getIgvOptions\n",
       " \n",
       "        render: function() {\n",
       "            var multiWidget = this;\n",
       "            console.log(\"entering render\");\n",
       "            this.listenTo(this.model, 'change:msgFromKernel', this.dispatchRequest, this);\n",
       "            this.masterTabsDiv = this.createMasterTabsDiv();\n",
       "            this.$el.append(this.masterTabsDiv);\n",
       "            this.listenTo(this.model, 'change:frameHeight', this.frameDimensionsChanged, this);\n",
       "            setTimeout(function(){\n",
       "               window.browser = igv.createBrowser($(\"#igvDiv\"), multiWidget.getIgvOptions());\n",
       "               //window.browser.on('locuschange', function(referenceFrame, chromLocString){multiWidget.chromLocString=chromLocString});\n",
       "               window.browser.on('locuschange', function(referenceFrame, chromLocString){\n",
       "                   multiWidget.updateChromLocStringToKernel(multiWidget, chromLocString)});\n",
       "               setTimeout(function() {\n",
       "                   console.log(\"about to call tabs()\");\n",
       "                    $(\"#masterTabsDiv\").tabs({\n",
       "                       activate: function(){\n",
       "                         console.log(\"tabs Activate\");\n",
       "                         console.log(\"cyInitialized: \" + window.cyInitialized);\n",
       "                         if(!window.cyInitialized){\n",
       "                            cy.fit(200);   // condition this on first time display only\n",
       "                            window.cyInitialized = true;\n",
       "                            }\n",
       "                         cy.resize();\n",
       "                       }});\n",
       "                   $(\"[href='#tab-2']\").trigger(\"click\");\n",
       "                   }, 8000);\n",
       "               }, 3000);\n",
       "            setTimeout(function(){\n",
       "               var options = multiWidget.getCyOptions();\n",
       "               console.log(JSON.stringify(options));\n",
       "               window.cy = cytoscape(multiWidget.getCyOptions());\n",
       "               console.log(\"window.cy created\")\n",
       "               $(\"#cyDiv\").height(800);\n",
       "               $(\"#cyFitButton\").click(function(){console.log(\"fit!\"); cy.fit(50)});\n",
       "               $(\"#cySFNButton\").click(function(){console.log(\"sfn\"); cy.nodes(':selected').neighborhood().nodes().select()});\n",
       "               cy.fit(100);\n",
       "               }, 1000);\n",
       "             }, // render\n",
       "\n",
       "        dispatchRequest: function(){\n",
       "           console.log(\"dispatchRequest\");\n",
       "           var msgRaw = this.model.get(\"msgFromKernel\");\n",
       "           var msg = JSON.parse(msgRaw);\n",
       "           console.log(msg);\n",
       "           console.log(\"========================\");\n",
       "           console.log(this);\n",
       "           switch(msg.cmd) {\n",
       "              case 'ping':\n",
       "                console.log(\"ping! from the kernel\");\n",
       "                break;\n",
       "              case 'deleteGraph':\n",
       "                cy.edges().remove();\n",
       "                cy.nodes().remove();\n",
       "                break;\n",
       "              case 'layout':\n",
       "                 var layoutName = msg.payload;\n",
       "                 cy.layout({\"name\": layoutName})\n",
       "                 break;\n",
       "              case 'loadNetworkStyleFile':\n",
       "                var styleFile = msg.payload;\n",
       "                this.loadNetworkStyleFile(styleFile);\n",
       "                break;\n",
       "              case 'tfGridLayout':\n",
       "                cy.nodes().filter(\"[type='TF']\").layout({name: \"grid\"})\n",
       "                break;\n",
       "              case 'selectedNodeGridLayout':\n",
       "                cy.nodes(\":selected\").layout({name: \"grid\"})\n",
       "                break;\n",
       "              case 'addGraph':\n",
       "                console.log(\"--- addGraph\")\n",
       "                var jsonGraph = msg.payload;\n",
       "                console.log(jsonGraph)\n",
       "                cy.json(jsonGraph);\n",
       "                cy.fit(100);\n",
       "                $(\"[href='#tab-1']\").trigger(\"click\");\n",
       "                break;\n",
       "              case 'fit':\n",
       "                 var margin = msg.payload;\n",
       "                 console.log(\"fit with margin: \" + margin)\n",
       "                 cy.fit(margin);\n",
       "                 break;\n",
       "               case 'fitSelected':\n",
       "                 var margin = msg.payload;\n",
       "                 console.log(\"fit with margin: \" + margin)\n",
       "                 cy.fit(cy.nodes(\":selected\"), margin);\n",
       "                 break;\n",
       "\n",
       "\n",
       "            default:\n",
       "               console.log(\"unrecognized msg.cmd: \" + msg.cmd);\n",
       "             } // switch\n",
       "           }, \n",
       "\n",
       "       updateChromLocStringToKernel: function(multiWidget, newString){\n",
       "           console.log(\"xxx \" + newString);\n",
       "           var jsonString = JSON.stringify({cmd: \"updateChromLocString\",\n",
       "                                            status: \"request\",\n",
       "                                            callback: \"\",\n",
       "                                            payload: newString});\n",
       "            multiWidget.model.set(\"msgFromBrowser\", jsonString);\n",
       "            multiWidget.touch()\n",
       "            },\n",
       "                                                \n",
       "        loadNetworkStyleFile: function(filename){\n",
       "           console.log(\"--- entering loadNetworkStyleFile\")\n",
       "           var cyObj = window.cy\n",
       "           var str = window.location.href;\n",
       "           var url = str.substr(0, str.lastIndexOf(\"/\")) + \"/\" + filename;\n",
       "           url = url.replace(\"/notebooks/\", \"/files/\");\n",
       "           console.log(\"--- loadNetworkStyleFile: \" +  url);\n",
       "            $.getScript(url)\n",
       "              .done(function(script, textStatus) {\n",
       "                 console.log(textStatus);\n",
       "                 cyObj.style(vizmap);\n",
       "                 })\n",
       "             .fail(function( jqxhr, settings, exception ) {\n",
       "                console.log(\"getScript error trying to read \" + filename);\n",
       "                console.log(\"exception: \");\n",
       "                console.log(exception);\n",
       "                });\n",
       "          },\n",
       "\n",
       "\n",
       "        frameDimensionsChanged: function(){\n",
       "           console.log(\"frameDimensionsChanged\");\n",
       "           var oldHeight = $(\"#mainDiv\").height()\n",
       "           var oldWidth = $(\"#mainDiv\").width()\n",
       "           var newHeight = this.model.get(\"frameHeight\");\n",
       "           var msg = \"<center>tabs demo, height: \" + oldHeight + \" -> \" + newHeight + \"</center>\";\n",
       "           $(\"#mainDiv\").html(msg);\n",
       "           $(\"#masterTabsDiv\").height(newHeight);\n",
       "           }, \n",
       "    });\n",
       "    return {\n",
       "        TabsView: TabsView\n",
       "    };\n",
       "});"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%%javascript\n",
    "\"use strict\"\n",
    "require.config({\n",
    "    shim: {'bootstrap': {'deps' :['jquery']},\n",
    "           'igv':       {'deps' :['jquery', 'jquery-ui', 'bootstrap']}\n",
    "           },\n",
    "\n",
    "    paths: {'jquery'    :   'http://code.jquery.com/jquery-1.12.4.min',\n",
    "            'jquery-ui' :   'http://code.jquery.com/ui/1.12.1/jquery-ui.min',\n",
    "            'cytoscape' :   'http://cytoscape.github.io/cytoscape.js/api/cytoscape.js-latest/cytoscape',\n",
    "            //'cytoscape' :   'http://localhost:8099/js/cytoscape-2.7.10',\n",
    "            'bootstrap' :   'http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min',\n",
    "            'igv'       :   'http://igv.org/web/release/1.0.6/igv-1.0.6'\n",
    "           }\n",
    "      });\n",
    "\n",
    "require.undef('tabsDemo')\n",
    "\n",
    "define('tabsDemo', [\"jupyter-js-widgets\", \"jquery\", \"jquery-ui\", \"cytoscape\", \"igv\"], \n",
    "       function(widgets, $, ui, cytoscape, igv) {\n",
    "    \n",
    "    var TabsView = widgets.DOMWidgetView.extend({\n",
    "\n",
    "        initialize: function() {\n",
    "           this.options = {}\n",
    "           this.chromLocString = \"\";\n",
    "           console.log(\"constructing TabsView\");\n",
    "           this.frameHeight = \"800px\";\n",
    "           window.cyInitialized = false;\n",
    "           },\n",
    "\n",
    "        resizeHandler: function(){\n",
    "           console.log(\"TabsView resizeHandler\")            \n",
    "           },\n",
    "        \n",
    "        createMasterTabsDiv: function(){\n",
    "           var masterTabsDiv = $(\"<div id='masterTabsDiv' style='border:1px solid gray; height: 1200px; width: 97%'></div>\");\n",
    "           var list = $(\"<ul/>\");\n",
    "           list.append(\"<li><a href='#tab-2'>igv</a></li>\");\n",
    "           list.append(\"<li><a href='#tab-1'>cytoscape</a></li>\");\n",
    "           list.append(\"<li><a href='#tab-3'>three</a></li>\");\n",
    "           masterTabsDiv.append(list);\n",
    "\n",
    "           var tab2 = $(\"<div id='tab-1'></div>\");\n",
    "            \n",
    "           tab2.append(\"<div id='cyOuterDiv' style='border:1px solid red; height:1000px;'>\" +\n",
    "                       \"<div id='cyMenubarDiv' style='background-color: lightgray; height:20px'>\" + \n",
    "                       \"<button id='cyFitButton'>Fit</button>\" +\n",
    "                       \"<button id='cySFNButton'>SFN</button>\" +\n",
    "                       \"<button id='cyHideUnselectedButton'>Hide Unselected</button>\" +\n",
    "                       \"<button id='cyShowAllButton'>Show All</button>\" +\n",
    "                       \"</div>\" +\n",
    "                       \"<div id='cyDiv' style='background-color: white; height: 960x'></div> </div>\");\n",
    "\n",
    "           var tab1 = $(\"<div id='tab-2'></div>\");\n",
    "           tab1.append(\"<div id='igvDiv' style='border:1px solid green; height:1000px;'></div>\");\n",
    "            \n",
    "           var tab3 = $(\"<div id='tab-3'>contents 3</div>\");\n",
    "            \n",
    "           masterTabsDiv.append(tab1);\n",
    "           masterTabsDiv.append(tab2);\n",
    "           masterTabsDiv.append(tab3); \n",
    "           return(masterTabsDiv);\n",
    "           },\n",
    "         \n",
    "        getCyOptions: function(){\n",
    "           var value = {container: $(\"#cyDiv\"), \n",
    "                                      elements: {nodes: [{data: {id:'a'}}],\n",
    "                                                 edges: [{data:{source:'a', target:'a'}}]},\n",
    "                                      style: cytoscape.stylesheet()\n",
    "                                        .selector('node').style({'background-color': '#d22',\n",
    "                                                                 'label': 'data(id)',\n",
    "                                                                 'text-valign': 'center',\n",
    "                                                                 'text-halign': 'center',\n",
    "                                                                 'border-width': 1})\n",
    "                                         .selector('edge').style({'line-color': 'black',\n",
    "                                                                  'target-arrow-shape': 'triangle',\n",
    "                                                                  'target-arrow-color': 'black',\n",
    "                                                                  'curve-style': 'bezier'})\n",
    "                       };\n",
    "            return(value);\n",
    "            }, // getCyOptions\n",
    "        \n",
    "        \n",
    "        getIgvOptions: function(){\n",
    "           var igvOptionsLocal = {locus: \"7:101,165,560-101,165,630\", // 5:88,621,548-88,999,827\",\n",
    "             reference: {id: \"geneSymbols_hg38\",\n",
    "                fastaURL: \"http://localhost/data/genomes/human_g1k_v37_decoy.fasta\",\n",
    "                 cytobandURL: \"http://localhost/data/annotations/b37_cytoband.txt\"\n",
    "                 },\n",
    "                tracks: [\n",
    "                  {name: 'Gencode v24',\n",
    "                   url: \"http://localhost://data/hg38/gencode.v24.annotation.sorted.gtf.gz\",\n",
    "                  indexURL: \"http://localhost://data/hg38/gencode.v24.annotation.sorted.gtf.gz.tbi\",\n",
    "                  format: 'gtf',\n",
    "                  visibilityWindow: 2000000,\n",
    "                  displayMode: 'EXPANDED'\n",
    "                  },\n",
    "                 {name: 'geneSymbols_hg38',\n",
    "                  url: 'http://localhost/data/hg38/geneSymbolSearch.bed',\n",
    "                  indexed: false,\n",
    "                  searchable: true,\n",
    "                  //visibilityWindow: 5000000,\n",
    "                  displayMode: 'COLLAPSED',\n",
    "                  color: \"#448844\"\n",
    "                  },\n",
    "                 {name: \"igap gwas\",\n",
    "                  url: 'http://localhost/data/hg38/variants/igap.bed',\n",
    "                  indexed: false,\n",
    "                  searchable: true,\n",
    "                  //visibilityWindow: 5000000,\n",
    "                  displayMode: 'EXPANDED',\n",
    "                  color: \"#884444\"\n",
    "                  }\n",
    "                  ]\n",
    "              }; // igvOptionsLocal\n",
    "             return(igvOptionsLocal);\n",
    "           }, // getIgvOptions\n",
    " \n",
    "        render: function() {\n",
    "            var multiWidget = this;\n",
    "            console.log(\"entering render\");\n",
    "            this.listenTo(this.model, 'change:msgFromKernel', this.dispatchRequest, this);\n",
    "            this.masterTabsDiv = this.createMasterTabsDiv();\n",
    "            this.$el.append(this.masterTabsDiv);\n",
    "            this.listenTo(this.model, 'change:frameHeight', this.frameDimensionsChanged, this);\n",
    "            setTimeout(function(){\n",
    "               window.browser = igv.createBrowser($(\"#igvDiv\"), multiWidget.getIgvOptions());\n",
    "               //window.browser.on('locuschange', function(referenceFrame, chromLocString){multiWidget.chromLocString=chromLocString});\n",
    "               window.browser.on('locuschange', function(referenceFrame, chromLocString){\n",
    "                   multiWidget.updateChromLocStringToKernel(multiWidget, chromLocString)});\n",
    "               setTimeout(function() {\n",
    "                   console.log(\"about to call tabs()\");\n",
    "                    $(\"#masterTabsDiv\").tabs({\n",
    "                       activate: function(){\n",
    "                         console.log(\"tabs Activate\");\n",
    "                         console.log(\"cyInitialized: \" + window.cyInitialized);\n",
    "                         if(!window.cyInitialized){\n",
    "                            cy.fit(200);   // condition this on first time display only\n",
    "                            window.cyInitialized = true;\n",
    "                            }\n",
    "                         cy.resize();\n",
    "                       }});\n",
    "                   $(\"[href='#tab-2']\").trigger(\"click\");\n",
    "                   }, 8000);\n",
    "               }, 3000);\n",
    "            setTimeout(function(){\n",
    "               var options = multiWidget.getCyOptions();\n",
    "               console.log(JSON.stringify(options));\n",
    "               window.cy = cytoscape(multiWidget.getCyOptions());\n",
    "               console.log(\"window.cy created\")\n",
    "               $(\"#cyDiv\").height(800);\n",
    "               $(\"#cyFitButton\").click(function(){console.log(\"fit!\"); cy.fit(50)});\n",
    "               $(\"#cySFNButton\").click(function(){console.log(\"sfn\"); cy.nodes(':selected').neighborhood().nodes().select()});\n",
    "               cy.fit(100);\n",
    "               }, 1000);\n",
    "             }, // render\n",
    "\n",
    "        dispatchRequest: function(){\n",
    "           console.log(\"dispatchRequest\");\n",
    "           var msgRaw = this.model.get(\"msgFromKernel\");\n",
    "           var msg = JSON.parse(msgRaw);\n",
    "           console.log(msg);\n",
    "           console.log(\"========================\");\n",
    "           console.log(this);\n",
    "           switch(msg.cmd) {\n",
    "              case 'ping':\n",
    "                console.log(\"ping! from the kernel\");\n",
    "                break;\n",
    "              case 'deleteGraph':\n",
    "                cy.edges().remove();\n",
    "                cy.nodes().remove();\n",
    "                break;\n",
    "              case 'layout':\n",
    "                 var layoutName = msg.payload;\n",
    "                 cy.layout({\"name\": layoutName})\n",
    "                 break;\n",
    "              case 'loadNetworkStyleFile':\n",
    "                var styleFile = msg.payload;\n",
    "                this.loadNetworkStyleFile(styleFile);\n",
    "                break;\n",
    "              case 'tfGridLayout':\n",
    "                cy.nodes().filter(\"[type='TF']\").layout({name: \"grid\"})\n",
    "                break;\n",
    "              case 'selectedNodeGridLayout':\n",
    "                cy.nodes(\":selected\").layout({name: \"grid\"})\n",
    "                break;\n",
    "              case 'addGraph':\n",
    "                console.log(\"--- addGraph\")\n",
    "                var jsonGraph = msg.payload;\n",
    "                console.log(jsonGraph)\n",
    "                cy.json(jsonGraph);\n",
    "                cy.fit(100);\n",
    "                $(\"[href='#tab-1']\").trigger(\"click\");\n",
    "                break;\n",
    "              case 'fit':\n",
    "                 var margin = msg.payload;\n",
    "                 console.log(\"fit with margin: \" + margin)\n",
    "                 cy.fit(margin);\n",
    "                 break;\n",
    "               case 'fitSelected':\n",
    "                 var margin = msg.payload;\n",
    "                 console.log(\"fit with margin: \" + margin)\n",
    "                 cy.fit(cy.nodes(\":selected\"), margin);\n",
    "                 break;\n",
    "\n",
    "\n",
    "            default:\n",
    "               console.log(\"unrecognized msg.cmd: \" + msg.cmd);\n",
    "             } // switch\n",
    "           }, \n",
    "\n",
    "       updateChromLocStringToKernel: function(multiWidget, newString){\n",
    "           console.log(\"xxx \" + newString);\n",
    "           var jsonString = JSON.stringify({cmd: \"updateChromLocString\",\n",
    "                                            status: \"request\",\n",
    "                                            callback: \"\",\n",
    "                                            payload: newString});\n",
    "            multiWidget.model.set(\"msgFromBrowser\", jsonString);\n",
    "            multiWidget.touch()\n",
    "            },\n",
    "                                                \n",
    "        loadNetworkStyleFile: function(filename){\n",
    "           console.log(\"--- entering loadNetworkStyleFile\")\n",
    "           var cyObj = window.cy\n",
    "           var str = window.location.href;\n",
    "           var url = str.substr(0, str.lastIndexOf(\"/\")) + \"/\" + filename;\n",
    "           url = url.replace(\"/notebooks/\", \"/files/\");\n",
    "           console.log(\"--- loadNetworkStyleFile: \" +  url);\n",
    "            $.getScript(url)\n",
    "              .done(function(script, textStatus) {\n",
    "                 console.log(textStatus);\n",
    "                 cyObj.style(vizmap);\n",
    "                 })\n",
    "             .fail(function( jqxhr, settings, exception ) {\n",
    "                console.log(\"getScript error trying to read \" + filename);\n",
    "                console.log(\"exception: \");\n",
    "                console.log(exception);\n",
    "                });\n",
    "          },\n",
    "\n",
    "\n",
    "        frameDimensionsChanged: function(){\n",
    "           console.log(\"frameDimensionsChanged\");\n",
    "           var oldHeight = $(\"#mainDiv\").height()\n",
    "           var oldWidth = $(\"#mainDiv\").width()\n",
    "           var newHeight = this.model.get(\"frameHeight\");\n",
    "           var msg = \"<center>tabs demo, height: \" + oldHeight + \" -> \" + newHeight + \"</center>\";\n",
    "           $(\"#mainDiv\").html(msg);\n",
    "           $(\"#masterTabsDiv\").height(newHeight);\n",
    "           }, \n",
    "    });\n",
    "    return {\n",
    "        TabsView: TabsView\n",
    "    };\n",
    "});"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "a3d747cc1d8646c59fd1fb70967736c8"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "app = TabsWidget()\n",
    "display(app)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "app.deleteGraph()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "7:101,166,103-101,166,281\n"
     ]
    }
   ],
   "source": [
    "print(app.getChromLocString())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 127,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import zmq"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 128,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<zmq.sugar.socket.Socket at 0x1047cbdc8>"
      ]
     },
     "execution_count": 128,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "socketContext = zmq.Context()\n",
    "socket = socketContext.socket(zmq.REQ)\n",
    "socket.connect(\"tcp://localhost:%s\" % '5557')\n",
    "socket"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 129,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\"cmd\": \"ping\", \"status\": \"request\", \"payload\": \"\", \"callback\": \"\"}\n",
      "{'cmd': {}, 'status': ['result'], 'payload': ['pong'], 'callback': ['']}\n"
     ]
    }
   ],
   "source": [
    "msg = {\"cmd\": \"ping\", \"status\": \"request\", \"callback\": \"\", \"payload\": \"\"}\n",
    "msg_json = json.dumps(msg)\n",
    "print(msg_json)\n",
    "socket.send_string(json.dumps(msg))\n",
    "print(json.loads(socket.recv_string()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "msg = json.dumps({\"cmd\": \"getTestNetwork\", \"status\": \"request\", \"callback\": \"\", \"payload\": \"VGF\"})\n",
    "socket.send_string(msg)\n",
    "gjson = json.loads(socket.recv_string())[\"payload\"]\n",
    "gjson"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "app.deleteGraph()\n",
    "app.addGraph(gjson)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\"cmd\": \"createGeneModel\", \"status\": \"request\", \"payload\": {\"footprintRegion\": \"7:101,166,157-101,166,196\", \"targetGene\": \"VGF\"}, \"callback\": \"\"}\n"
     ]
    }
   ],
   "source": [
    "region = app.getChromLocString()\n",
    "targetGene = \"VGF\"\n",
    "msg = json.dumps({\"cmd\": \"createGeneModel\", \"status\": \"request\", \"callback\": \"\", \n",
    "                  \"payload\": {\"targetGene\": targetGene, \"footprintRegion\": region}})\n",
    "print(msg)\n",
    "socket.send_string(msg)\n",
    "gjson = json.loads(socket.recv_string())[\"payload\"][0]  # not sure why it comes in as a 1-element array"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 131,
   "metadata": {},
   "outputs": [],
   "source": [
    "#print(gjson)\n",
    "#print(json.loads(gjson))\n",
    "graphData = json.loads(gjson)\n",
    "#graphData"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 132,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "app.deleteGraph()\n",
    "app.addGraph(graphData)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "app.loadNetworkStyleFile(\"style-purityControlsNodeSize.js\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "app.fit()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "app.fitSelected()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "app.selectedNodeGridLayout(\"foo\")"
   ]<commit_msg>cyjs and igv js libraries now checked for, placeholder resizeHandler added<commit_after>{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import requests\n",
    "import ipywidgets as widgets\n",
    "import json\n",
    "import time\n",
    "import os\n",
    "from IPython.display import display, HTML\n",
    "from traitlets import Int, Unicode, observe"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### two javascript libraries which may not always be available.  detect  that  if so."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "assert(requests.get('http://cytoscape.github.io/cytoscape.js/api/cytoscape.js-latest/cytoscape.js').status_code == 200)\n",
    "assert(requests.get('http://igv.org/web/release/1.0.6/igv-1.0.6.js').status_code == 200)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<link rel=\"stylesheet\" type=\"text/css\" href=\"//igv.org/web/release/1.0.6/igv-1.0.6.css\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "display(HTML('<link rel=\"stylesheet\" type=\"text/css\" href=\"//igv.org/web/release/1.0.6/igv-1.0.6.css\">'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class TabsWidget(widgets.DOMWidget):\n",
    "    \n",
    "    _view_name = Unicode('TabsView').tag(sync=True)\n",
    "    _view_module = Unicode('tabsDemo').tag(sync=True)\n",
    "    frameHeight = Int(300).tag(sync=True)\n",
    "    _chromLocString = \"chr1:0-0\";\n",
    "    _rawMessage = \"\";\n",
    "    _incomingMessage = {};\n",
    "    msgFromKernel = Unicode(\"{}\").tag(sync=True)\n",
    "    msgFromBrowser = Unicode(\"{}\").tag(sync=True)\n",
    "    status = \"initial status message\\n\"\n",
    "\n",
    "       # ensure that any ensuing message is seen as novel in the browser\n",
    "       # the message (a json-ified string) is a mutable traitlet.  the browser only sees \n",
    "       # the message if it changes\n",
    "    def _sendResetMessageToBrowser(self):  \n",
    "       self.msgFromKernel = json.dumps({\"cmd\": \"cleanSlate\", \"status\": \"nop\", \"callback\": \"\", \"payload\": \"\"});\n",
    "\n",
    "    def setHeight(self, height):\n",
    "       print(\"setHeight(%d) \"% height)\n",
    "       self.frameHeight = height\n",
    "        \n",
    "    def getChromLocString(self):\n",
    "        return self._chromLocString\n",
    "    \n",
    "    def ping(self):\n",
    "        self._sendResetMessageToBrowser()\n",
    "        self.msgFromKernel = json.dumps({\"cmd\": \"ping\", \"status\": \"request\", \"callback\": \"\", \"payload\": \"\"});\n",
    "\n",
    "    def deleteGraph(self):\n",
    "      self._sendResetMessageToBrowser()\n",
    "      self.msgFromKernel = json.dumps({\"cmd\": \"deleteGraph\", \"status\": \"request\", \"callback\": \"\", \"payload\": \"\"});\n",
    "\n",
    "    def addGraph(self, gjson):\n",
    "      self._sendResetMessageToBrowser();\n",
    "      self.msgFromKernel = json.dumps({\"cmd\": \"addGraph\", \"status\": \"request\",\n",
    "                                       \"callback\": \"\",    \"payload\": gjson});\n",
    "    def fitSelected(self, margin=50):\n",
    "      self._sendResetMessageToBrowser();\n",
    "      self.status += \"entering fitSelected (%d)\\n\" % margin\n",
    "      self.msgFromKernel = json.dumps({\"cmd\": \"fitSelected\", \"status\": \"request\", \"callback\": \"\", \"payload\": margin});\n",
    "        \n",
    "    def fit(self, margin=50):\n",
    "      self._sendResetMessageToBrowser();\n",
    "      self.status += \"entering fit (%d)\\n\" % margin\n",
    "      self.msgFromKernel = json.dumps({\"cmd\": \"fit\", \"status\": \"request\", \"callback\": \"\", \"payload\": margin});\n",
    "\n",
    "\n",
    "    def availableLayouts(self):\n",
    "      self._sendResetMessageToBrowser();\n",
    "\n",
    "      return([\"grid\", \"null\", \"random\", \"cose\", \"circle\", \"concentric\", \"breadthfirst\"]);\n",
    "\n",
    "    def layout(self, name):\n",
    "      self._sendResetMessageToBrowser();\n",
    "      self.msgFromKernel = json.dumps({\"cmd\": \"layout\", \"status\": \"request\", \"callback\": \"\", \"payload\": name});\n",
    "\n",
    "    def tfGridLayout(self):\n",
    "      self._sendResetMessageToBrowser();\n",
    "      self.msgFromKernel = json.dumps({\"cmd\": \"tfGridLayout\", \"status\": \"request\", \"callback\": \"\", \"payload\": \"\"});\n",
    "\n",
    "    def selectedNodeGridLayout(self, name):\n",
    "      self._sendResetMessageToBrowser();\n",
    "      self.msgFromKernel = json.dumps({\"cmd\": \"selectedNodeGridLayout\", \"status\": \"request\", \"callback\": \"\", \"payload\": \"\"});\n",
    "\n",
    "\n",
    "    def loadNetworkStyleFile(self, filename):\n",
    "      if(not os.path.isfile(filename)):\n",
    "        print(\"file '%s' not found\" % filename)\n",
    "        return;\n",
    "      self._sendResetMessageToBrowser();\n",
    "      self.msgFromKernel = json.dumps({\"cmd\": \"loadNetworkStyleFile\", \"status\": \"request\", \"callback\": \"\", \n",
    "                                       \"payload\": filename});\n",
    "        \n",
    "\n",
    "    @observe('msgFromBrowser')\n",
    "    def msg_arrived(self, change):\n",
    "       #self.status += \"msgFromBrowser has arrived: %f\\n\" % time.time()\n",
    "       self._rawMessage = change['new']\n",
    "       #self.status += \"rawMessage: %s\\n\" % self._rawMessage\n",
    "       self._incomingMessage = json.loads(self._rawMessage)\n",
    "       cmd = self._incomingMessage[\"cmd\"]\n",
    "       #self.status += \"cmd: %s\\n\"  % cmd\n",
    "       if(cmd == \"updateChromLocString\"):\n",
    "          self._chromLocString = self._incomingMessage[\"payload\"]\n",
    "       else:\n",
    "         self.status += \"unrecognized cmd: '%s'\" % cmd\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<style>\n",
       "    div#notebook-container    { width: 97%; }\n",
       "    div#menubar-container     { width: 65%; }\n",
       "    div#maintoolbar-container { width: 99%; }\n",
       "</style>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "display(HTML(data=\"\"\"\n",
    "<style>\n",
    "    div#notebook-container    { width: 97%; }\n",
    "    div#menubar-container     { width: 65%; }\n",
    "    div#maintoolbar-container { width: 99%; }\n",
    "</style>\n",
    "\"\"\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "\"use strict\"\n",
       "require.config({\n",
       "    shim: {'bootstrap': {'deps' :['jquery']},\n",
       "           'igv':       {'deps' :['jquery', 'jquery-ui', 'bootstrap']}\n",
       "           },\n",
       "\n",
       "    paths: {'jquery'    :   'http://code.jquery.com/jquery-1.12.4.min',\n",
       "            'jquery-ui' :   'http://code.jquery.com/ui/1.12.1/jquery-ui.min',\n",
       "            'cytoscape' :   'http://cytoscape.github.io/cytoscape.js/api/cytoscape.js-latest/cytoscape',\n",
       "            'bootstrap' :   'http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min',\n",
       "            'igv'       :   'http://igv.org/web/release/1.0.6/igv-1.0.6'\n",
       "           }\n",
       "      });\n",
       "\n",
       "require.undef('tabsDemo')\n",
       "\n",
       "define('tabsDemo', [\"jupyter-js-widgets\", \"jquery\", \"jquery-ui\", \"cytoscape\", \"igv\"], \n",
       "       function(widgets, $, ui, cytoscape, igv) {\n",
       "    \n",
       "    var TabsView = widgets.DOMWidgetView.extend({\n",
       "\n",
       "        initialize: function() {\n",
       "           this.options = {}\n",
       "           this.chromLocString = \"\";\n",
       "           console.log(\"constructing TabsView\");\n",
       "           this.frameHeight = \"800px\";\n",
       "           window.cyInitialized = false;\n",
       "           },\n",
       "\n",
       "        resizeHandler: function(){\n",
       "           console.log(\"TabsView resizeHandler\")            \n",
       "           },\n",
       "        \n",
       "        createMasterTabsDiv: function(){\n",
       "           var masterTabsDiv = $(\"<div id='masterTabsDiv' style='border:1px solid gray; height: 1200px; width: 97%'></div>\");\n",
       "           var list = $(\"<ul/>\");\n",
       "           list.append(\"<li><a href='#tab-2'>igv</a></li>\");\n",
       "           list.append(\"<li><a href='#tab-1'>cytoscape</a></li>\");\n",
       "           list.append(\"<li><a href='#tab-3'>three</a></li>\");\n",
       "           masterTabsDiv.append(list);\n",
       "\n",
       "           var tab2 = $(\"<div id='tab-1'></div>\");\n",
       "            \n",
       "           tab2.append(\"<div id='cyOuterDiv' style='border:1px solid red; width: 98% height: 95%;'>\" +\n",
       "                       \"<div id='cyMenubarDiv' style='background-color: lightgray; height: 25px'>\" + \n",
       "                       \"<button id='cyFitButton'>Fit</button>\" +\n",
       "                       \"<button id='cyFitSelectedButton'>Fit Selected</button>\" +\n",
       "                       \"<button id='cySFNButton'>SFN</button>\" +\n",
       "                       \"<button id='cyHideUnselectedButton'>Hide Unselected</button>\" +\n",
       "                       \"<button id='cyShowAllButton'>Show All</button>\" +\n",
       "                       \"</div>\" +\n",
       "                       \"<div id='cyDiv' style='background-color: white; border:1px solid gree; width: 98%; height: 98%'></div> </div>\");\n",
       "\n",
       "           var tab1 = $(\"<div id='tab-2'></div>\");\n",
       "           tab1.append(\"<div id='igvDiv' style='border:1px solid green; height:1000px;'></div>\");\n",
       "            \n",
       "           var tab3 = $(\"<div id='tab-3'>contents 3</div>\");\n",
       "            \n",
       "           masterTabsDiv.append(tab1);\n",
       "           masterTabsDiv.append(tab2);\n",
       "           masterTabsDiv.append(tab3); \n",
       "           return(masterTabsDiv);\n",
       "           },\n",
       "         \n",
       "        getCyOptions: function(){\n",
       "           console.log(\"entering getCyOptions\");\n",
       "           debugger;\n",
       "           var value = {container: $(\"#cyDiv\"), \n",
       "                                      elements: {nodes: [{data: {id:'a'}}],\n",
       "                                                 edges: [{data:{source:'a', target:'a'}}]},\n",
       "                                      style: cytoscape.stylesheet()\n",
       "                                        .selector('node').style({'background-color': '#d22',\n",
       "                                                                 'label': 'data(id)',\n",
       "                                                                 'text-valign': 'center',\n",
       "                                                                 'text-halign': 'center',\n",
       "                                                                 'border-width': 1})\n",
       "                                         .selector('edge').style({'line-color': 'black',\n",
       "                                                                  'target-arrow-shape': 'triangle',\n",
       "                                                                  'target-arrow-color': 'black',\n",
       "                                                                  'curve-style': 'bezier'})\n",
       "                       };\n",
       "            console.log(\"about to leave getCyOptions\")\n",
       "            return(value);\n",
       "            }, // getCyOptions\n",
       "        \n",
       "        \n",
       "        getIgvOptions: function(){\n",
       "           var igvOptionsLocal = {locus: \"7:101,165,560-101,165,630\", // 5:88,621,548-88,999,827\",\n",
       "             reference: {id: \"geneSymbols_hg38\",\n",
       "                fastaURL: \"http://localhost/data/genomes/human_g1k_v37_decoy.fasta\",\n",
       "                 cytobandURL: \"http://localhost/data/annotations/b37_cytoband.txt\"\n",
       "                 },\n",
       "                tracks: [\n",
       "                  {name: '<NAME>',\n",
       "                   url: \"http://localhost://data/hg38/gencode.v24.annotation.sorted.gtf.gz\",\n",
       "                  indexURL: \"http://localhost://data/hg38/gencode.v24.annotation.sorted.gtf.gz.tbi\",\n",
       "                  format: 'gtf',\n",
       "                  visibilityWindow: 2000000,\n",
       "                  displayMode: 'EXPANDED'\n",
       "                  },\n",
       "                 {name: 'geneSymbols_hg38',\n",
       "                  url: 'http://localhost/data/hg38/geneSymbolSearch.bed',\n",
       "                  indexed: false,\n",
       "                  searchable: true,\n",
       "                  //visibilityWindow: 5000000,\n",
       "                  displayMode: 'COLLAPSED',\n",
       "                  color: \"#448844\"\n",
       "                  },\n",
       "                 {name: \"igap gwas\",\n",
       "                  url: 'http://localhost/data/hg38/variants/igap.bed',\n",
       "                  indexed: false,\n",
       "                  searchable: true,\n",
       "                  //visibilityWindow: 5000000,\n",
       "                  displayMode: 'EXPANDED',\n",
       "                  color: \"#884444\"\n",
       "                  }\n",
       "                  ]\n",
       "              }; // igvOptionsLocal\n",
       "             return(igvOptionsLocal);\n",
       "           }, // getIgvOptions\n",
       " \n",
       "        render: function() {\n",
       "            var multiWidget = this;\n",
       "            $(window).resize(multiWidget.resizeHandler);\n",
       "            console.log(\"entering render\");\n",
       "            this.listenTo(this.model, 'change:msgFromKernel', this.dispatchRequest, this);\n",
       "            this.masterTabsDiv = this.createMasterTabsDiv();\n",
       "            this.$el.append(this.masterTabsDiv);\n",
       "            this.listenTo(this.model, 'change:frameHeight', this.frameDimensionsChanged, this);\n",
       "            setTimeout(function(){\n",
       "               window.browser = igv.createBrowser($(\"#igvDiv\"), multiWidget.getIgvOptions());\n",
       "               //window.browser.on('locuschange', function(referenceFrame, chromLocString){multiWidget.chromLocString=chromLocString});\n",
       "               window.browser.on('locuschange', function(referenceFrame, chromLocString){\n",
       "                   multiWidget.updateChromLocStringToKernel(multiWidget, chromLocString)});\n",
       "               setTimeout(function() {\n",
       "                   console.log(\"about to call tabs()\");\n",
       "                    $(\"#masterTabsDiv\").tabs({\n",
       "                       activate: function(){\n",
       "                         console.log(\"tabs Activate\");\n",
       "                         console.log(\"cyInitialized: \" + window.cyInitialized);\n",
       "                         if(!window.cyInitialized){\n",
       "                            cy.fit(200);   // condition this on first time display only\n",
       "                            window.cyInitialized = true;\n",
       "                            }\n",
       "                         cy.resize();\n",
       "                       }});\n",
       "                   $(\"[href='#tab-2']\").trigger(\"click\");\n",
       "                   }, 8000);\n",
       "               }, 3000);\n",
       "            setTimeout(function(){\n",
       "               console.log(\"starting cy creation setTimeout\")\n",
       "               console.log(\"   cyDiv defined? \" + $(\"#cyDiv\"));\n",
       "               var options = multiWidget.getCyOptions();\n",
       "               console.log(\"   after  getCyOptions\")\n",
       "               console.log(JSON.stringify(options));\n",
       "               window.cy = cytoscape(multiWidget.getCyOptions());\n",
       "               console.log(\"window.cy created\")\n",
       "               $(\"#cyDiv\").height(800);\n",
       "               $(\"#cyFitButton\").click(function(){cy.fit(50)});\n",
       "               $(\"#cyFitSelectedButton\").click(function(){cy.fit(cy.nodes(\":selected\"), 50)});\n",
       "               $(\"#cySFNButton\").click(function(){cy.nodes(':selected').neighborhood().nodes().select()});\n",
       "               $(\"#cyHideUnselectedButton\").click(function(){cy.nodes(\":unselected\").hide()});\n",
       "               $(\"#cyShowAllButton\").click(function(){cy.nodes().show(); cy.edges().show()});\n",
       "               cy.fit(100);\n",
       "               }, 1000);\n",
       "             }, // render\n",
       "\n",
       "        dispatchRequest: function(){\n",
       "           console.log(\"dispatchRequest\");\n",
       "           var msgRaw = this.model.get(\"msgFromKernel\");\n",
       "           var msg = JSON.parse(msgRaw);\n",
       "           console.log(msg);\n",
       "           console.log(\"========================\");\n",
       "           console.log(this);\n",
       "           switch(msg.cmd) {\n",
       "              case 'ping':\n",
       "                console.log(\"ping! from the kernel\");\n",
       "                break;\n",
       "              case 'deleteGraph':\n",
       "                cy.edges().remove();\n",
       "                cy.nodes().remove();\n",
       "                break;\n",
       "              case 'layout':\n",
       "                 var layoutName = msg.payload;\n",
       "                 cy.layout({\"name\": layoutName})\n",
       "                 break;\n",
       "              case 'loadNetworkStyleFile':\n",
       "                var styleFile = msg.payload;\n",
       "                this.loadNetworkStyleFile(styleFile);\n",
       "                break;\n",
       "              case 'tfGridLayout':\n",
       "                cy.nodes().filter(\"[type='TF']\").layout({name: \"grid\"})\n",
       "                break;\n",
       "              case 'selectedNodeGridLayout':\n",
       "                cy.nodes(\":selected\").layout({name: \"grid\"})\n",
       "                break;\n",
       "              case 'addGraph':\n",
       "                console.log(\"--- addGraph\")\n",
       "                var jsonGraph = msg.payload;\n",
       "                console.log(jsonGraph)\n",
       "                cy.json(jsonGraph);\n",
       "                cy.fit(100);\n",
       "                $(\"[href='#tab-1']\").trigger(\"click\");\n",
       "                break;\n",
       "              case 'fit':\n",
       "                 var margin = msg.payload;\n",
       "                 console.log(\"fit with margin: \" + margin)\n",
       "                 cy.fit(margin);\n",
       "                 break;\n",
       "               case 'fitSelected':\n",
       "                 var margin = msg.payload;\n",
       "                 console.log(\"fit with margin: \" + margin)\n",
       "                 cy.fit(cy.nodes(\":selected\"), margin);\n",
       "                 break;\n",
       "\n",
       "\n",
       "            default:\n",
       "               console.log(\"unrecognized msg.cmd: \" + msg.cmd);\n",
       "             } // switch\n",
       "           }, \n",
       "\n",
       "       updateChromLocStringToKernel: function(multiWidget, newString){\n",
       "           console.log(\"xxx \" + newString);\n",
       "           var jsonString = JSON.stringify({cmd: \"updateChromLocString\",\n",
       "                                            status: \"request\",\n",
       "                                            callback: \"\",\n",
       "                                            payload: newString});\n",
       "            multiWidget.model.set(\"msgFromBrowser\", jsonString);\n",
       "            multiWidget.touch()\n",
       "            },\n",
       "                                                \n",
       "        loadNetworkStyleFile: function(filename){\n",
       "           console.log(\"--- entering loadNetworkStyleFile\")\n",
       "           var cyObj = window.cy\n",
       "           var str = window.location.href;\n",
       "           var url = str.substr(0, str.lastIndexOf(\"/\")) + \"/\" + filename;\n",
       "           url = url.replace(\"/notebooks/\", \"/files/\");\n",
       "           console.log(\"--- loadNetworkStyleFile: \" +  url);\n",
       "            $.getScript(url)\n",
       "              .done(function(script, textStatus) {\n",
       "                 console.log(textStatus);\n",
       "                 cyObj.style(vizmap);\n",
       "                 })\n",
       "             .fail(function( jqxhr, settings, exception ) {\n",
       "                console.log(\"getScript error trying to read \" + filename);\n",
       "                console.log(\"exception: \");\n",
       "                console.log(exception);\n",
       "                });\n",
       "          },\n",
       "\n",
       "\n",
       "        frameDimensionsChanged: function(){\n",
       "           console.log(\"frameDimensionsChanged\");\n",
       "           var oldHeight = $(\"#mainDiv\").height()\n",
       "           var oldWidth = $(\"#mainDiv\").width()\n",
       "           var newHeight = this.model.get(\"frameHeight\");\n",
       "           var msg = \"<center>tabs demo, height: \" + oldHeight + \" -> \" + newHeight + \"</center>\";\n",
       "           $(\"#mainDiv\").html(msg);\n",
       "           $(\"#masterTabsDiv\").height(newHeight);\n",
       "           }, \n",
       "    });\n",
       "    return {\n",
       "        TabsView: TabsView\n",
       "    };\n",
       "});"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%%javascript\n",
    "\"use strict\"\n",
    "require.config({\n",
    "    shim: {'bootstrap': {'deps' :['jquery']},\n",
    "           'igv':       {'deps' :['jquery', 'jquery-ui', 'bootstrap']}\n",
    "           },\n",
    "\n",
    "    paths: {'jquery'    :   'http://code.jquery.com/jquery-1.12.4.min',\n",
    "            'jquery-ui' :   'http://code.jquery.com/ui/1.12.1/jquery-ui.min',\n",
    "            'cytoscape' :   'http://cytoscape.github.io/cytoscape.js/api/cytoscape.js-latest/cytoscape',\n",
    "            'bootstrap' :   'http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min',\n",
    "            'igv'       :   'http://igv.org/web/release/1.0.6/igv-1.0.6'\n",
    "           }\n",
    "      });\n",
    "\n",
    "require.undef('tabsDemo')\n",
    "\n",
    "define('tabsDemo', [\"jupyter-js-widgets\", \"jquery\", \"jquery-ui\", \"cytoscape\", \"igv\"], \n",
    "       function(widgets, $, ui, cytoscape, igv) {\n",
    "    \n",
    "    var TabsView = widgets.DOMWidgetView.extend({\n",
    "\n",
    "        initialize: function() {\n",
    "           this.options = {}\n",
    "           this.chromLocString = \"\";\n",
    "           console.log(\"constructing TabsView\");\n",
    "           this.frameHeight = \"800px\";\n",
    "           window.cyInitialized = false;\n",
    "           },\n",
    "\n",
    "        resizeHandler: function(){\n",
    "           console.log(\"TabsView resizeHandler\")            \n",
    "           },\n",
    "        \n",
    "        createMasterTabsDiv: function(){\n",
    "           var masterTabsDiv = $(\"<div id='masterTabsDiv' style='border:1px solid gray; height: 1200px; width: 97%'></div>\");\n",
    "           var list = $(\"<ul/>\");\n",
    "           list.append(\"<li><a href='#tab-2'>igv</a></li>\");\n",
    "           list.append(\"<li><a href='#tab-1'>cytoscape</a></li>\");\n",
    "           list.append(\"<li><a href='#tab-3'>three</a></li>\");\n",
    "           masterTabsDiv.append(list);\n",
    "\n",
    "           var tab2 = $(\"<div id='tab-1'></div>\");\n",
    "            \n",
    "           tab2.append(\"<div id='cyOuterDiv' style='border:1px solid red; width: 98% height: 95%;'>\" +\n",
    "                       \"<div id='cyMenubarDiv' style='background-color: lightgray; height: 25px'>\" + \n",
    "                       \"<button id='cyFitButton'>Fit</button>\" +\n",
    "                       \"<button id='cyFitSelectedButton'>Fit Selected</button>\" +\n",
    "                       \"<button id='cySFNButton'>SFN</button>\" +\n",
    "                       \"<button id='cyHideUnselectedButton'>Hide Unselected</button>\" +\n",
    "                       \"<button id='cyShowAllButton'>Show All</button>\" +\n",
    "                       \"</div>\" +\n",
    "                       \"<div id='cyDiv' style='background-color: white; border:1px solid gree; width: 98%; height: 98%'></div> </div>\");\n",
    "\n",
    "           var tab1 = $(\"<div id='tab-2'></div>\");\n",
    "           tab1.append(\"<div id='igvDiv' style='border:1px solid green; height:1000px;'></div>\");\n",
    "            \n",
    "           var tab3 = $(\"<div id='tab-3'>contents 3</div>\");\n",
    "            \n",
    "           masterTabsDiv.append(tab1);\n",
    "           masterTabsDiv.append(tab2);\n",
    "           masterTabsDiv.append(tab3); \n",
    "           return(masterTabsDiv);\n",
    "           },\n",
    "         \n",
    "        getCyOptions: function(){\n",
    "           console.log(\"entering getCyOptions\");\n",
    "           debugger;\n",
    "           var value = {container: $(\"#cyDiv\"), \n",
    "                                      elements: {nodes: [{data: {id:'a'}}],\n",
    "                                                 edges: [{data:{source:'a', target:'a'}}]},\n",
    "                                      style: cytoscape.stylesheet()\n",
    "                                        .selector('node').style({'background-color': '#d22',\n",
    "                                                                 'label': 'data(id)',\n",
    "                                                                 'text-valign': 'center',\n",
    "                                                                 'text-halign': 'center',\n",
    "                                                                 'border-width': 1})\n",
    "                                         .selector('edge').style({'line-color': 'black',\n",
    "                                                                  'target-arrow-shape': 'triangle',\n",
    "                                                                  'target-arrow-color': 'black',\n",
    "                                                                  'curve-style': 'bezier'})\n",
    "                       };\n",
    "            console.log(\"about to leave getCyOptions\")\n",
    "            return(value);\n",
    "            }, // getCyOptions\n",
    "        \n",
    "        \n",
    "        getIgvOptions: function(){\n",
    "           var igvOptionsLocal = {locus: \"7:101,165,560-101,165,630\", // 5:88,621,548-88,999,827\",\n",
    "             reference: {id: \"geneSymbols_hg38\",\n",
    "                fastaURL: \"http://localhost/data/genomes/human_g1k_v37_decoy.fasta\",\n",
    "                 cytobandURL: \"http://localhost/data/annotations/b37_cytoband.txt\"\n",
    "                 },\n",
    "                tracks: [\n",
    "                  {name: 'Gencode v24',\n",
    "                   url: \"http://localhost://data/hg38/gencode.v24.annotation.sorted.gtf.gz\",\n",
    "                  indexURL: \"http://localhost://data/hg38/gencode.v24.annotation.sorted.gtf.gz.tbi\",\n",
    "                  format: 'gtf',\n",
    "                  visibilityWindow: 2000000,\n",
    "                  displayMode: 'EXPANDED'\n",
    "                  },\n",
    "                 {name: 'geneSymbols_hg38',\n",
    "                  url: 'http://localhost/data/hg38/geneSymbolSearch.bed',\n",
    "                  indexed: false,\n",
    "                  searchable: true,\n",
    "                  //visibilityWindow: 5000000,\n",
    "                  displayMode: 'COLLAPSED',\n",
    "                  color: \"#448844\"\n",
    "                  },\n",
    "                 {name: \"igap gwas\",\n",
    "                  url: 'http://localhost/data/hg38/variants/igap.bed',\n",
    "                  indexed: false,\n",
    "                  searchable: true,\n",
    "                  //visibilityWindow: 5000000,\n",
    "                  displayMode: 'EXPANDED',\n",
    "                  color: \"#884444\"\n",
    "                  }\n",
    "                  ]\n",
    "              }; // igvOptionsLocal\n",
    "             return(igvOptionsLocal);\n",
    "           }, // getIgvOptions\n",
    " \n",
    "        render: function() {\n",
    "            var multiWidget = this;\n",
    "            $(window).resize(multiWidget.resizeHandler);\n",
    "            console.log(\"entering render\");\n",
    "            this.listenTo(this.model, 'change:msgFromKernel', this.dispatchRequest, this);\n",
    "            this.masterTabsDiv = this.createMasterTabsDiv();\n",
    "            this.$el.append(this.masterTabsDiv);\n",
    "            this.listenTo(this.model, 'change:frameHeight', this.frameDimensionsChanged, this);\n",
    "            setTimeout(function(){\n",
    "               window.browser = igv.createBrowser($(\"#igvDiv\"), multiWidget.getIgvOptions());\n",
    "               //window.browser.on('locuschange', function(referenceFrame, chromLocString){multiWidget.chromLocString=chromLocString});\n",
    "               window.browser.on('locuschange', function(referenceFrame, chromLocString){\n",
    "                   multiWidget.updateChromLocStringToKernel(multiWidget, chromLocString)});\n",
    "               setTimeout(function() {\n",
    "                   console.log(\"about to call tabs()\");\n",
    "                    $(\"#masterTabsDiv\").tabs({\n",
    "                       activate: function(){\n",
    "                         console.log(\"tabs Activate\");\n",
    "                         console.log(\"cyInitialized: \" + window.cyInitialized);\n",
    "                         if(!window.cyInitialized){\n",
    "                            cy.fit(200);   // condition this on first time display only\n",
    "                            window.cyInitialized = true;\n",
    "                            }\n",
    "                         cy.resize();\n",
    "                       }});\n",
    "                   $(\"[href='#tab-2']\").trigger(\"click\");\n",
    "                   }, 8000);\n",
    "               }, 3000);\n",
    "            setTimeout(function(){\n",
    "               console.log(\"starting cy creation setTimeout\")\n",
    "               console.log(\"   cyDiv defined? \" + $(\"#cyDiv\"));\n",
    "               var options = multiWidget.getCyOptions();\n",
    "               console.log(\"   after  getCyOptions\")\n",
    "               console.log(JSON.stringify(options));\n",
    "               window.cy = cytoscape(multiWidget.getCyOptions());\n",
    "               console.log(\"window.cy created\")\n",
    "               $(\"#cyDiv\").height(800);\n",
    "               $(\"#cyFitButton\").click(function(){cy.fit(50)});\n",
    "               $(\"#cyFitSelectedButton\").click(function(){cy.fit(cy.nodes(\":selected\"), 50)});\n",
    "               $(\"#cySFNButton\").click(function(){cy.nodes(':selected').neighborhood().nodes().select()});\n",
    "               $(\"#cyHideUnselectedButton\").click(function(){cy.nodes(\":unselected\").hide()});\n",
    "               $(\"#cyShowAllButton\").click(function(){cy.nodes().show(); cy.edges().show()});\n",
    "               cy.fit(100);\n",
    "               }, 1000);\n",
    "             }, // render\n",
    "\n",
    "        dispatchRequest: function(){\n",
    "           console.log(\"dispatchRequest\");\n",
    "           var msgRaw = this.model.get(\"msgFromKernel\");\n",
    "           var msg = JSON.parse(msgRaw);\n",
    "           console.log(msg);\n",
    "           console.log(\"========================\");\n",
    "           console.log(this);\n",
    "           switch(msg.cmd) {\n",
    "              case 'ping':\n",
    "                console.log(\"ping! from the kernel\");\n",
    "                break;\n",
    "              case 'deleteGraph':\n",
    "                cy.edges().remove();\n",
    "                cy.nodes().remove();\n",
    "                break;\n",
    "              case 'layout':\n",
    "                 var layoutName = msg.payload;\n",
    "                 cy.layout({\"name\": layoutName})\n",
    "                 break;\n",
    "              case 'loadNetworkStyleFile':\n",
    "                var styleFile = msg.payload;\n",
    "                this.loadNetworkStyleFile(styleFile);\n",
    "                break;\n",
    "              case 'tfGridLayout':\n",
    "                cy.nodes().filter(\"[type='TF']\").layout({name: \"grid\"})\n",
    "                break;\n",
    "              case 'selectedNodeGridLayout':\n",
    "                cy.nodes(\":selected\").layout({name: \"grid\"})\n",
    "                break;\n",
    "              case 'addGraph':\n",
    "                console.log(\"--- addGraph\")\n",
    "                var jsonGraph = msg.payload;\n",
    "                console.log(jsonGraph)\n",
    "                cy.json(jsonGraph);\n",
    "                cy.fit(100);\n",
    "                $(\"[href='#tab-1']\").trigger(\"click\");\n",
    "                break;\n",
    "              case 'fit':\n",
    "                 var margin = msg.payload;\n",
    "                 console.log(\"fit with margin: \" + margin)\n",
    "                 cy.fit(margin);\n",
    "                 break;\n",
    "               case 'fitSelected':\n",
    "                 var margin = msg.payload;\n",
    "                 console.log(\"fit with margin: \" + margin)\n",
    "                 cy.fit(cy.nodes(\":selected\"), margin);\n",
    "                 break;\n",
    "\n",
    "\n",
    "            default:\n",
    "               console.log(\"unrecognized msg.cmd: \" + msg.cmd);\n",
    "             } // switch\n",
    "           }, \n",
    "\n",
    "       updateChromLocStringToKernel: function(multiWidget, newString){\n",
    "           console.log(\"xxx \" + newString);\n",
    "           var jsonString = JSON.stringify({cmd: \"updateChromLocString\",\n",
    "                                            status: \"request\",\n",
    "                                            callback: \"\",\n",
    "                                            payload: newString});\n",
    "            multiWidget.model.set(\"msgFromBrowser\", jsonString);\n",
    "            multiWidget.touch()\n",
    "            },\n",
    "                                                \n",
    "        loadNetworkStyleFile: function(filename){\n",
    "           console.log(\"--- entering loadNetworkStyleFile\")\n",
    "           var cyObj = window.cy\n",
    "           var str = window.location.href;\n",
    "           var url = str.substr(0, str.lastIndexOf(\"/\")) + \"/\" + filename;\n",
    "           url = url.replace(\"/notebooks/\", \"/files/\");\n",
    "           console.log(\"--- loadNetworkStyleFile: \" +  url);\n",
    "            $.getScript(url)\n",
    "              .done(function(script, textStatus) {\n",
    "                 console.log(textStatus);\n",
    "                 cyObj.style(vizmap);\n",
    "                 })\n",
    "             .fail(function( jqxhr, settings, exception ) {\n",
    "                console.log(\"getScript error trying to read \" + filename);\n",
    "                console.log(\"exception: \");\n",
    "                console.log(exception);\n",
    "                });\n",
    "          },\n",
    "\n",
    "\n",
    "        frameDimensionsChanged: function(){\n",
    "           console.log(\"frameDimensionsChanged\");\n",
    "           var oldHeight = $(\"#mainDiv\").height()\n",
    "           var oldWidth = $(\"#mainDiv\").width()\n",
    "           var newHeight = this.model.get(\"frameHeight\");\n",
    "           var msg = \"<center>tabs demo, height: \" + oldHeight + \" -> \" + newHeight + \"</center>\";\n",
    "           $(\"#mainDiv\").html(msg);\n",
    "           $(\"#masterTabsDiv\").height(newHeight);\n",
    "           }, \n",
    "    });\n",
    "    return {\n",
    "        TabsView: TabsView\n",
    "    };\n",
    "});"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "b02addc1c8db41d39ef4e06024973269"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "app = TabsWidget()\n",
    "display(app)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "app.deleteGraph()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "7:101,165,503-101,165,838\n"
     ]
    }
   ],
   "source": [
    "print(app.getChromLocString())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import zmq"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<zmq.sugar.socket.Socket at 0x1046ae7c8>"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "socketContext = zmq.Context()\n",
    "socket = socketContext.socket(zmq.REQ)\n",
    "socket.connect(\"tcp://localhost:%s\" % '5557')\n",
    "socket"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\"callback\": \"\", \"cmd\": \"ping\", \"status\": \"request\", \"payload\": \"\"}\n",
      "{'callback': [''], 'cmd': {}, 'status': ['result'], 'payload': ['pong']}\n"
     ]
    }
   ],
   "source": [
    "msg = {\"cmd\": \"ping\", \"status\": \"request\", \"callback\": \"\", \"payload\": \"\"}\n",
    "msg_json = json.dumps(msg)\n",
    "print(msg_json)\n",
    "socket.send_string(json.dumps(msg))\n",
    "print(json.loads(socket.recv_string()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "msg = json.dumps({\"cmd\": \"getTestNetwork\", \"status\": \"request\", \"callback\": \"\", \"payload\": \"VGF\"})\n",
    "socket.send_string(msg)\n",
    "gjson = json.loads(socket.recv_string())[\"payload\"]\n",
    "gjson"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "app.deleteGraph()\n",
    "app.addGraph(gjson)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "region = app.getChromLocString()\n",
    "targetGene = \"VGF\"\n",
    "msg = json.dumps({\"cmd\": \"createGeneModel\", \"status\": \"request\", \"callback\": \"\", \n",
    "                  \"payload\": {\"targetGene\": targetGene, \"footprintRegion\": region}})\n",
    "socket.send_string(msg)\n",
    "gjson = json.loads(socket.recv_string())[\"payload\"][0] \n",
    "graphData = json.loads(gjson)\n",
    "app.deleteGraph()\n",
    "app.addGraph(graphData)\n",
    "app.loadNetworkStyleFile(\"style-purityControlsNodeSize.js\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "graphData = json.loads(gjson)\n",
    "app.deleteGraph()\n",
    "app.addGraph(graphData)\n",
    "app.loadNetworkStyleFile(\"style-purityControlsNodeSize.js\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "app.fit()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "app.fitSelected()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "app.selectedNodeGridLayout(\"foo\")"
   ]
{'fraction_non_alphanumeric': 0.21189447047570617, 'fraction_numerical': 0.01239814512125725, 'mean_word_length': 1.367132867132867, 'pattern_counts': {'":': 426, '<': 184, '<?xml version=': 0, '>': 188, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 178, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1774734', 'n_tokens_mistral': 26690, 'n_tokens_neox': 25284, 'n_words': 3514}