Skip to content

Commit

Permalink
Merge pull request #5129 from bokeh/mattpap/5125_npm_package
Browse files Browse the repository at this point in the history
Allow to require("bokehjs") in node.js
  • Loading branch information
mattpap committed Sep 14, 2016
2 parents 2ff0a11 + cca8f21 commit 9650b10
Show file tree
Hide file tree
Showing 8 changed files with 193 additions and 4 deletions.
1 change: 1 addition & 0 deletions bokehjs/examples/electron/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/node_modules/
6 changes: 6 additions & 0 deletions bokehjs/examples/electron/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# bokehjs-electron-quick-start

```bash
# Install dependencies and run the app
npm install && npm start
```
14 changes: 14 additions & 0 deletions bokehjs/examples/electron/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>BokehJS in Electron</title>
<link rel="stylesheet" href="node_modules/bokehjs/build/css/bokeh.css" type="text/css" />
</head>
<body>
</body>
<script>
// You can also require other files to run in this process
require('./renderer.js')
</script>
</html>
53 changes: 53 additions & 0 deletions bokehjs/examples/electron/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
const electron = require('electron')
// Module to control application life.
const app = electron.app
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow

function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({width: 1000, height: 800})

// and load the index.html of the app.
mainWindow.loadURL(`file://${__dirname}/index.html`)

// Open the DevTools.
mainWindow.webContents.openDevTools()

// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)

// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})

app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
21 changes: 21 additions & 0 deletions bokehjs/examples/electron/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "bokehjs-electron-quick-start",
"version": "1.0.0",
"description": "A minimal BokehJS Electron application",
"keywords": ["bokeh", "bokehjs", "electron"],
"license": "BSD-3-Clause",
"repository": {
"type": "git",
"url": "https://github.com/bokeh/bokeh.git"
},
"main": "main.js",
"scripts": {
"start": "node_modules/.bin/electron ."
},
"devDependencies": {
"electron": "^1.3.4"
},
"dependencies": {
"bokehjs": "../.."
}
}
56 changes: 56 additions & 0 deletions bokehjs/examples/electron/renderer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// This file is required by the index.html file and will
// be executed in the renderer process for that window.
// All of the Node.js APIs are available in this process.

const Bokeh = require("bokehjs");

const plt = Bokeh.Plotting;
const _ = Bokeh._;

Bokeh.set_log_level("info");
Bokeh.logger.info(`Bokeh ${Bokeh.version}`);

const M = 100
const xx = []
const yy = []

for (let y = 0; y <= M; y += 4) {
for (let x = 0; x <= M; x += 4) {
xx.push(x)
yy.push(y)
}
}

const N = xx.length
const indices = _.range(N).map((i) => i.toString())
const radii = _.range(N).map((i) => Math.random()*0.4 + 1.7)

const colors = []
for (let [r, g] of _.zip(xx.map((x) => 50 + 2*x), yy.map((y) => 30 + 2*y))) {
colors.push(plt.color(r, g, 150))
}

const source = new Bokeh.ColumnDataSource({
data: {x: xx, y: yy, radius: radii, colors: colors }
})

const tools = "pan,crosshair,wheel_zoom,box_zoom,reset,hover,save"

const p = plt.figure({title: "Hoverful Scatter", tools: tools})

const circles = p.circle({field: "x"}, {field: "y"}, {source: source, radius: radii,
fill_color: colors, fill_alpha: 0.6, line_color: null})

p.text({field: "x"}, {field: "y"}, indices, {source: source, alpha: 0.5,
text_font_size: "5pt", text_baseline: "middle", text_align: "center"})

const hover = p.toolbar.select_one(Bokeh.HoverTool)
hover.tooltips = (source, info) => {
const div = document.createElement("div")
div.style.width = "200px"
div.style.height = "75px"
div.style.backgroundColor = source.data["colors"][info.index]
return div
}

plt.show(p)
9 changes: 5 additions & 4 deletions bokehjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,8 @@
"gulp-if": "^2.0.0",
"merge": "^1.2.0",
"logtrap": "^0.0.1",
"hammerjs": "^2.0.4",
"mocha": "^2.2.5",
"mocha-jsdom": "^1.0.0",
"numbro": "https://github.com/bokeh/numbro.git#b4ccab0",
"phantomjs-prebuilt": "2.1.7",
"proxyquire": "1.7.10",
"run-sequence": "^1.0.0",
Expand All @@ -66,6 +64,7 @@
"websocket":"^1.0.22",
"typings": "^0.7.9",
"typings-core": "^0.2.11",
"coffee-script": "^1.10.0",
"detective": "^4.3.1",
"jslint": "^0.10.3",
"acorn": "^3.3.0",
Expand Down Expand Up @@ -99,11 +98,13 @@
"proj4": "^2.3.10",
"sprintf": "^0.1.5",
"timezone": "0.0.38",
"coffee-script": "^1.9.3"
"hammerjs": "^2.0.4",
"numbro": "https://github.com/bokeh/numbro.git#b4ccab0",
"root-require": "^0.3.1"
},
"scripts": {
"build": "gulp build",
"dev-build": "gulp dev-build"
},
"main": "build/js/bokeh.js"
"main": "build/js/tree/index.js"
}
37 changes: 37 additions & 0 deletions bokehjs/src/coffee/index.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
path = require "path"
assert = require "assert"
rootRequire = require("root-require")

root = rootRequire.packpath.parent()
pkg = rootRequire("./package.json")

module.constructor.prototype.require = (modulePath) ->
assert(modulePath, 'missing path')
assert(typeof modulePath == 'string', 'path must be a string')

overridePath = pkg.browser[modulePath]
if overridePath?
modulePath = path.join(root, overridePath)

return this.constructor._load(modulePath, this)

bokehjs = () ->
if not window?.document?
throw new Error("bokehjs requires a window with a document. If your
runtime environment doesn't provide those, e.g. pure node.js, you
can use jsdom library to configure window and document.")

Bokeh = require './main'
_ = Bokeh._

load_plugin = (path) ->
plugin = require(path)
_.extend(Bokeh, _.omit(plugin, "models"))
Bokeh.Models.register_locations(plugin.models ? {})

load_plugin('./api')
load_plugin('./models/widgets/main')

return Bokeh

module.exports = if window?.document? then bokehjs() else bokehjs

0 comments on commit 9650b10

Please sign in to comment.