Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BokehJS and node.js integration #1589

Closed
bryevdv opened this issue Dec 24, 2014 · 34 comments
Closed

BokehJS and node.js integration #1589

bryevdv opened this issue Dec 24, 2014 · 34 comments

Comments

@bryevdv
Copy link
Member

bryevdv commented Dec 24, 2014

This is a necessary prerequisite to adopting node-canvas for headless static output as described in #538.

@mattpap and @tswicegood your input is very appreciated when you have time.

@bryevdv bryevdv added this to the short-term milestone Dec 24, 2014
@bryevdv
Copy link
Member Author

bryevdv commented Dec 24, 2014

I have been experimenting trying to get the following to execute in node:

// this seems necessary to have window, document, etc but maybe there is another or better way
var jsdom = require("jsdom");
global.document = jsdom.jsdom();
global.window = document.defaultView;
global.navigator = require('navigator')

// this is surely garbage, but not sure what else to do
global.jQuery = require('jquery')
global.$ = global.jQuery
global.window.jQuery = global.jQuery

Bokeh = require("./bokeh.js");

// pukes here
Bokeh.set_log_level("info");

$(function() {
    var modelid = "a8115598-9957-4dad-81be-0f8f03fab30e";
    var modeltype = "PlotContext";
    var elementid = "14c57239-c7da-4c0d-ac53-272e34eae54c";
    Bokeh.logger.info("Realizing plot:")
    Bokeh.logger.info(" - modeltype: PlotContext");
    Bokeh.logger.info(" - modelid: a8115598-9957-4dad-81be-0f8f03fab30e");
    Bokeh.logger.info(" - elementid: 14c57239-c7da-4c0d-ac53-272e34eae54c");
    var all_models = [{"attributes": {"tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "a2a91543-d2f4-441b-bfcc-9c4d8f76273b", "num_minor_ticks": 5}, "type": "BasicTicker", "id": "a2a91543-d2f4-441b-bfcc-9c4d8f76273b"}, {"attributes": {"plot": {"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7"}, "dimensions": ["width", "height"], "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "2fff48fb-a48f-4dc3-aeff-4dd2161f0eda"}, "type": "PanTool", "id": "2fff48fb-a48f-4dc3-aeff-4dd2161f0eda"}, {"attributes": {"line_color": {"value": "#1f77b4"}, "line_alpha": {"units": "data", "value": 0.1}, "fill_color": {"value": "#1f77b4"}, "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "fill_alpha": {"units": "data", "value": 0.1}, "y": {"units": "data", "field": "y"}, "x": {"units": "data", "field": "x"}, "id": "fa365b1f-40f5-45ab-acf0-9f89b44f945e", "size": {"units": "screen", "value": 10}}, "type": "Circle", "id": "fa365b1f-40f5-45ab-acf0-9f89b44f945e"}, {"attributes": {"line_color": {"units": "data", "field": "line_color"}, "line_alpha": {"units": "data", "value": 1.0}, "fill_color": {"units": "data", "field": "fill_color"}, "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "fill_alpha": {"units": "data", "value": 0.2}, "y": {"units": "data", "field": "y"}, "x": {"units": "data", "field": "x"}, "id": "4e5958cf-e966-4f46-9c6d-52d882909935", "size": {"units": "screen", "value": 10}}, "type": "Circle", "id": "4e5958cf-e966-4f46-9c6d-52d882909935"}, {"attributes": {"doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "5f643ee8-3529-4327-b1b1-75d42814c38b", "tags": []}, "type": "BasicTickFormatter", "id": "5f643ee8-3529-4327-b1b1-75d42814c38b"}, {"attributes": {"nonselection_glyph": {"type": "Circle", "id": "fa365b1f-40f5-45ab-acf0-9f89b44f945e"}, "data_source": {"type": "ColumnDataSource", "id": "8515850a-fe60-4acc-9744-66d8d2fb3782"}, "name": null, "server_data_source": null, "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "selection_glyph": null, "id": "5c1402d5-8e90-4597-bce0-acc1c9d0feda", "glyph": {"type": "Circle", "id": "4e5958cf-e966-4f46-9c6d-52d882909935"}}, "type": "GlyphRenderer", "id": "5c1402d5-8e90-4597-bce0-acc1c9d0feda"}, {"attributes": {"plot": {"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7"}, "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "dimension": 0, "ticker": {"type": "BasicTicker", "id": "a2a91543-d2f4-441b-bfcc-9c4d8f76273b"}, "id": "281cb0a7-b161-415d-94d0-ea6477c7e7e1"}, "type": "Grid", "id": "281cb0a7-b161-415d-94d0-ea6477c7e7e1"}, {"attributes": {"sources": [{"source": {"type": "ColumnDataSource", "id": "8515850a-fe60-4acc-9744-66d8d2fb3782"}, "columns": ["x"]}], "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "785fc299-a873-4eaa-bc7a-597563c9e3c6"}, "type": "DataRange1d", "id": "785fc299-a873-4eaa-bc7a-597563c9e3c6"}, {"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7", "attributes": {"x_range": {"type": "DataRange1d", "id": "785fc299-a873-4eaa-bc7a-597563c9e3c6"}, "right": [], "tags": [], "tools": [{"type": "PanTool", "id": "2fff48fb-a48f-4dc3-aeff-4dd2161f0eda"}, {"type": "WheelZoomTool", "id": "27918bb7-3c81-4c57-b22a-dc16867cc225"}, {"type": "BoxZoomTool", "id": "33f7029c-f9ae-42e5-8bea-1e031bbecf62"}, {"type": "PreviewSaveTool", "id": "c66c8537-24d4-49a4-a901-fe51a63eed92"}, {"type": "ResizeTool", "id": "5269f11b-cebb-42a8-910c-068e1d0ee01f"}, {"type": "ResetTool", "id": "d7be6268-5bc5-4110-9d9e-8637501ac879"}], "title": "Iris Morphology", "extra_y_ranges": {}, "renderers": [{"type": "LinearAxis", "id": "7a4cef60-fef8-418e-8dce-5735a632443a"}, {"type": "Grid", "id": "281cb0a7-b161-415d-94d0-ea6477c7e7e1"}, {"type": "LinearAxis", "id": "c7c97009-eca8-403a-825f-21fc45a7b994"}, {"type": "Grid", "id": "40c58c15-7cdd-4f62-b8d9-bbb652749d47"}, {"type": "GlyphRenderer", "id": "5c1402d5-8e90-4597-bce0-acc1c9d0feda"}], "extra_x_ranges": {}, "below": [{"type": "LinearAxis", "id": "7a4cef60-fef8-418e-8dce-5735a632443a"}], "tool_events": {"type": "ToolEvents", "id": "0ff5dd6f-4319-456a-ae3d-1f2b5c39b5c7"}, "above": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "y_range": {"type": "DataRange1d", "id": "d6b16de2-db4f-4bd5-b33c-71c50a091d1c"}, "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7", "left": [{"type": "LinearAxis", "id": "c7c97009-eca8-403a-825f-21fc45a7b994"}]}}, {"attributes": {"plot": {"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7"}, "dimensions": ["width", "height"], "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "27918bb7-3c81-4c57-b22a-dc16867cc225"}, "type": "WheelZoomTool", "id": "27918bb7-3c81-4c57-b22a-dc16867cc225"}, {"attributes": {"sources": [{"source": {"type": "ColumnDataSource", "id": "8515850a-fe60-4acc-9744-66d8d2fb3782"}, "columns": ["y"]}], "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "d6b16de2-db4f-4bd5-b33c-71c50a091d1c"}, "type": "DataRange1d", "id": "d6b16de2-db4f-4bd5-b33c-71c50a091d1c"}, {"attributes": {"doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "f674a2f6-e917-4684-b877-3aa2fdd33dd5", "tags": []}, "type": "BasicTickFormatter", "id": "f674a2f6-e917-4684-b877-3aa2fdd33dd5"}, {"attributes": {"tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "e7944dd2-bbcb-435f-bc62-6da53efb1c83", "num_minor_ticks": 5}, "type": "BasicTicker", "id": "e7944dd2-bbcb-435f-bc62-6da53efb1c83"}, {"attributes": {"plot": {"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7"}, "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "dimension": 1, "ticker": {"type": "BasicTicker", "id": "e7944dd2-bbcb-435f-bc62-6da53efb1c83"}, "id": "40c58c15-7cdd-4f62-b8d9-bbb652749d47"}, "type": "Grid", "id": "40c58c15-7cdd-4f62-b8d9-bbb652749d47"}, {"attributes": {"geometries": [], "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "0ff5dd6f-4319-456a-ae3d-1f2b5c39b5c7"}, "type": "ToolEvents", "id": "0ff5dd6f-4319-456a-ae3d-1f2b5c39b5c7"}, {"attributes": {"plot": {"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7"}, "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "axis_label": "Petal Length", "formatter": {"type": "BasicTickFormatter", "id": "5f643ee8-3529-4327-b1b1-75d42814c38b"}, "ticker": {"type": "BasicTicker", "id": "a2a91543-d2f4-441b-bfcc-9c4d8f76273b"}, "id": "7a4cef60-fef8-418e-8dce-5735a632443a"}, "type": "LinearAxis", "id": "7a4cef60-fef8-418e-8dce-5735a632443a"}, {"attributes": {"plot": {"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7"}, "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "c66c8537-24d4-49a4-a901-fe51a63eed92"}, "type": "PreviewSaveTool", "id": "c66c8537-24d4-49a4-a901-fe51a63eed92"}, {"attributes": {"plot": {"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7"}, "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "axis_label": "Petal Width", "formatter": {"type": "BasicTickFormatter", "id": "f674a2f6-e917-4684-b877-3aa2fdd33dd5"}, "ticker": {"type": "BasicTicker", "id": "e7944dd2-bbcb-435f-bc62-6da53efb1c83"}, "id": "c7c97009-eca8-403a-825f-21fc45a7b994"}, "type": "LinearAxis", "id": "c7c97009-eca8-403a-825f-21fc45a7b994"}, {"attributes": {"plot": {"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7"}, "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "33f7029c-f9ae-42e5-8bea-1e031bbecf62"}, "type": "BoxZoomTool", "id": "33f7029c-f9ae-42e5-8bea-1e031bbecf62"}, {"attributes": {"plot": {"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7"}, "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "d7be6268-5bc5-4110-9d9e-8637501ac879"}, "type": "ResetTool", "id": "d7be6268-5bc5-4110-9d9e-8637501ac879"}, {"attributes": {"column_names": ["fill_color", "line_color", "x", "y"], "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "selected": [], "discrete_ranges": {}, "cont_ranges": {}, "data": {"line_color": ["red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue"], "x": [1.4, 1.4, 1.3, 1.5, 1.4, 1.7, 1.4, 1.5, 1.4, 1.5, 1.5, 1.6, 1.4, 1.1, 1.2, 1.5, 1.3, 1.4, 1.7, 1.5, 1.7, 1.5, 1.0, 1.7, 1.9, 1.6, 1.6, 1.5, 1.4, 1.6, 1.6, 1.5, 1.5, 1.4, 1.5, 1.2, 1.3, 1.4, 1.3, 1.5, 1.3, 1.3, 1.3, 1.6, 1.9, 1.4, 1.6, 1.4, 1.5, 1.4, 4.7, 4.5, 4.9, 4.0, 4.6, 4.5, 4.7, 3.3, 4.6, 3.9, 3.5, 4.2, 4.0, 4.7, 3.6, 4.4, 4.5, 4.1, 4.5, 3.9, 4.8, 4.0, 4.9, 4.7, 4.3, 4.4, 4.8, 5.0, 4.5, 3.5, 3.8, 3.7, 3.9, 5.1, 4.5, 4.5, 4.7, 4.4, 4.1, 4.0, 4.4, 4.6, 4.0, 3.3, 4.2, 4.2, 4.2, 4.3, 3.0, 4.1, 6.0, 5.1, 5.9, 5.6, 5.8, 6.6, 4.5, 6.3, 5.8, 6.1, 5.1, 5.3, 5.5, 5.0, 5.1, 5.3, 5.5, 6.7, 6.9, 5.0, 5.7, 4.9, 6.7, 4.9, 5.7, 6.0, 4.8, 4.9, 5.6, 5.8, 6.1, 6.4, 5.6, 5.1, 5.6, 6.1, 5.6, 5.5, 4.8, 5.4, 5.6, 5.1, 5.1, 5.9, 5.7, 5.2, 5.0, 5.2, 5.4, 5.1], "fill_color": ["red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue"], "y": [0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2, 1.4, 1.5, 1.5, 1.3, 1.5, 1.3, 1.6, 1.0, 1.3, 1.4, 1.0, 1.5, 1.0, 1.4, 1.3, 1.4, 1.5, 1.0, 1.5, 1.1, 1.8, 1.3, 1.5, 1.2, 1.3, 1.4, 1.4, 1.7, 1.5, 1.0, 1.1, 1.0, 1.2, 1.6, 1.5, 1.6, 1.5, 1.3, 1.3, 1.3, 1.2, 1.4, 1.2, 1.0, 1.3, 1.2, 1.3, 1.3, 1.1, 1.3, 2.5, 1.9, 2.1, 1.8, 2.2, 2.1, 1.7, 1.8, 1.8, 2.5, 2.0, 1.9, 2.1, 2.0, 2.4, 2.3, 1.8, 2.2, 2.3, 1.5, 2.3, 2.0, 2.0, 1.8, 2.1, 1.8, 1.8, 1.8, 2.1, 1.6, 1.9, 2.0, 2.2, 1.5, 1.4, 2.3, 2.4, 1.8, 1.8, 2.1, 2.4, 2.3, 1.9, 2.3, 2.5, 2.3, 1.9, 2.0, 2.3, 1.8]}, "id": "8515850a-fe60-4acc-9744-66d8d2fb3782"}, "type": "ColumnDataSource", "id": "8515850a-fe60-4acc-9744-66d8d2fb3782"}, {"attributes": {"plot": {"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7"}, "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "5269f11b-cebb-42a8-910c-068e1d0ee01f"}, "type": "ResizeTool", "id": "5269f11b-cebb-42a8-910c-068e1d0ee01f"}, {"attributes": {"tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "a8115598-9957-4dad-81be-0f8f03fab30e", "children": [{"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7"}]}, "type": "PlotContext", "id": "a8115598-9957-4dad-81be-0f8f03fab30e"}];
    Bokeh.load_models(all_models);
    var model = Bokeh.Collections(modeltype).get(modelid);
    var view = new model.default_view({model: model, el: '#14c57239-c7da-4c0d-ac53-272e34eae54c'});
    Bokeh.index[modelid] = view
});

I had to install node packages: navigator, jsdom, jquery, as well as apply the following patch to bokeh.js to even get as far as I did:

34516c34516
< //return root.sprintf = sprintf;
---
> return root.sprintf = sprintf;
34522,34525c34522,34524
<   // if (typeof module == "object" && module.exports) module.exports = definition();
<   // else if (typeof define == "function") define('timezone',definition);
<   // else this.tz = definition();
<   define('timezone',definition);
---
>   if (typeof module == "object" && module.exports) module.exports = definition();
>   else if (typeof define == "function") define('timezone',definition);
>   else this.tz = definition();

Ultimately I am sure it would be better to split off the non-widget, non-UI (tools) part of BokehJS to make it easier to use with node, but if there is something to be done in the short term, we should.

@hhuuggoo
Copy link
Contributor

@tswicegood probably has some comments

@bryevdv
Copy link
Member Author

bryevdv commented Dec 24, 2014

I pinged @tswicegood at the top. :)

@tswicegood
Copy link
Contributor

@bryevdv are you getting any errors when trying to run this? I don't currently have a development version of bokeh setup so I haven't tried your code but it looks roughly right (ignoring any potential issues with require.js/r.js).

Andrew and I just worked through setting up Backbone with Mocha in Node.js (using Browserify, though). One thing we did differently was use the jsdom.env someHtml, [jQueryPath], (err, window) -> style then used that window to assign to the global scope. Not as contained as I would like, but solved the problem for the most part (at least until we try to parallelize the tests).

@bryevdv
Copy link
Member Author

bryevdv commented Dec 29, 2014

Yes it blows up at the Bokeh.set_log_level("info"); line I don't remember exactly what I think the module was not defined or some such.

@tswicegood
Copy link
Contributor

Yeah -- at that point something is not shimmed correctly. Can you post in the stack trace?

@mattpap
Copy link
Contributor

mattpap commented Jan 29, 2015

I was able to correctly load bokehjs in node. The problem was that some of bokehjs' dependencies try to be smart and behave like node modules when they think is necessary. The effect was that require("bokeh.js") caused to return a reference to numeral.js instead of bokehjs, because numeral.js was the last module exhibiting this behavior and bokeh.js didn't behave like a node module. There were other issues to fix as well. Still there is one with loading timezone module, but for now I just disabled it.

This is far from getting plots to render. Currently, although I load jsdom, node-canvas and a few other node modules, bokeh.js doesn't seem to be aware of this and all calls, that should retrieve nodes from DOM, fail. I'm debugging this now, but that's slow, because there are subtle errors in jsdom at al. that cause node.js do terminate, e.g. when you try to show a node in debugger's repl.

@mattpap
Copy link
Contributor

mattpap commented Jan 29, 2015

So that was for require("bokeh.js"). Attempt to allow require("main") is a completely different story, where everything blows up in very peculiar ways.

@mattpap
Copy link
Contributor

mattpap commented Feb 2, 2015

For now I wasn't able to get anywhere near rendering a plot in node.js. Currently the issue is that node.js abruptly terminates when I try to use any HTML fragment that contains <canvas> element. It doesn't matter if I enable node-canvas or not (this is jsdom's fault). The error is as follows:

nodejs: /home/mateusz/.node-gyp/0.10.36/src/node_object_wrap.h:61: static T* node::ObjectWrap::Unwrap(v8::Handle<v8::Object>) [with T = Canvas]: Assertion `handle->InternalFieldCount() > 0' failed.

I tried different versions of node.js, including development 0.11.x branch.

@mattpap
Copy link
Contributor

mattpap commented Feb 2, 2015

To reproduce my results, you can use the following code:

// npm install -g jsdom location navigator canvas node-inspector

var JSDom = require("jsdom");
global.document = JSDom.jsdom();
global.window = document.parentWindow;
global.location = require("location");
global.navigator = require("navigator");
global.window.Canvas = require("canvas");

Bokeh = require("./bokeh.js");
Bokeh.set_log_level("info");

var all_models = [{"attributes": {"tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "a2a91543-d2f4-441b-bfcc-9c4d8f76273b", "num_minor_ticks": 5}, "type": "BasicTicker", "id": "a2a91543-d2f4-441b-bfcc-9c4d8f76273b"}, {"attributes": {"plot": {"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7"}, "dimensions": ["width", "height"], "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "2fff48fb-a48f-4dc3-aeff-4dd2161f0eda"}, "type": "PanTool", "id": "2fff48fb-a48f-4dc3-aeff-4dd2161f0eda"}, {"attributes": {"line_color": {"value": "#1f77b4"}, "line_alpha": {"units": "data", "value": 0.1}, "fill_color": {"value": "#1f77b4"}, "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "fill_alpha": {"units": "data", "value": 0.1}, "y": {"units": "data", "field": "y"}, "x": {"units": "data", "field": "x"}, "id": "fa365b1f-40f5-45ab-acf0-9f89b44f945e", "size": {"units": "screen", "value": 10}}, "type": "Circle", "id": "fa365b1f-40f5-45ab-acf0-9f89b44f945e"}, {"attributes": {"line_color": {"units": "data", "field": "line_color"}, "line_alpha": {"units": "data", "value": 1.0}, "fill_color": {"units": "data", "field": "fill_color"}, "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "fill_alpha": {"units": "data", "value": 0.2}, "y": {"units": "data", "field": "y"}, "x": {"units": "data", "field": "x"}, "id": "4e5958cf-e966-4f46-9c6d-52d882909935", "size": {"units": "screen", "value": 10}}, "type": "Circle", "id": "4e5958cf-e966-4f46-9c6d-52d882909935"}, {"attributes": {"doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "5f643ee8-3529-4327-b1b1-75d42814c38b", "tags": []}, "type": "BasicTickFormatter", "id": "5f643ee8-3529-4327-b1b1-75d42814c38b"}, {"attributes": {"nonselection_glyph": {"type": "Circle", "id": "fa365b1f-40f5-45ab-acf0-9f89b44f945e"}, "data_source": {"type": "ColumnDataSource", "id": "8515850a-fe60-4acc-9744-66d8d2fb3782"}, "name": null, "server_data_source": null, "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "selection_glyph": null, "id": "5c1402d5-8e90-4597-bce0-acc1c9d0feda", "glyph": {"type": "Circle", "id": "4e5958cf-e966-4f46-9c6d-52d882909935"}}, "type": "GlyphRenderer", "id": "5c1402d5-8e90-4597-bce0-acc1c9d0feda"}, {"attributes": {"plot": {"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7"}, "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "dimension": 0, "ticker": {"type": "BasicTicker", "id": "a2a91543-d2f4-441b-bfcc-9c4d8f76273b"}, "id": "281cb0a7-b161-415d-94d0-ea6477c7e7e1"}, "type": "Grid", "id": "281cb0a7-b161-415d-94d0-ea6477c7e7e1"}, {"attributes": {"sources": [{"source": {"type": "ColumnDataSource", "id": "8515850a-fe60-4acc-9744-66d8d2fb3782"}, "columns": ["x"]}], "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "785fc299-a873-4eaa-bc7a-597563c9e3c6"}, "type": "DataRange1d", "id": "785fc299-a873-4eaa-bc7a-597563c9e3c6"}, {"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7", "attributes": {"x_range": {"type": "DataRange1d", "id": "785fc299-a873-4eaa-bc7a-597563c9e3c6"}, "right": [], "tags": [], "tools": [{"type": "PanTool", "id": "2fff48fb-a48f-4dc3-aeff-4dd2161f0eda"}, {"type": "WheelZoomTool", "id": "27918bb7-3c81-4c57-b22a-dc16867cc225"}, {"type": "BoxZoomTool", "id": "33f7029c-f9ae-42e5-8bea-1e031bbecf62"}, {"type": "PreviewSaveTool", "id": "c66c8537-24d4-49a4-a901-fe51a63eed92"}, {"type": "ResizeTool", "id": "5269f11b-cebb-42a8-910c-068e1d0ee01f"}, {"type": "ResetTool", "id": "d7be6268-5bc5-4110-9d9e-8637501ac879"}], "title": "Iris Morphology", "extra_y_ranges": {}, "renderers": [{"type": "LinearAxis", "id": "7a4cef60-fef8-418e-8dce-5735a632443a"}, {"type": "Grid", "id": "281cb0a7-b161-415d-94d0-ea6477c7e7e1"}, {"type": "LinearAxis", "id": "c7c97009-eca8-403a-825f-21fc45a7b994"}, {"type": "Grid", "id": "40c58c15-7cdd-4f62-b8d9-bbb652749d47"}, {"type": "GlyphRenderer", "id": "5c1402d5-8e90-4597-bce0-acc1c9d0feda"}], "extra_x_ranges": {}, "below": [{"type": "LinearAxis", "id": "7a4cef60-fef8-418e-8dce-5735a632443a"}], "tool_events": {"type": "ToolEvents", "id": "0ff5dd6f-4319-456a-ae3d-1f2b5c39b5c7"}, "above": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "y_range": {"type": "DataRange1d", "id": "d6b16de2-db4f-4bd5-b33c-71c50a091d1c"}, "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7", "left": [{"type": "LinearAxis", "id": "c7c97009-eca8-403a-825f-21fc45a7b994"}]}}, {"attributes": {"plot": {"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7"}, "dimensions": ["width", "height"], "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "27918bb7-3c81-4c57-b22a-dc16867cc225"}, "type": "WheelZoomTool", "id": "27918bb7-3c81-4c57-b22a-dc16867cc225"}, {"attributes": {"sources": [{"source": {"type": "ColumnDataSource", "id": "8515850a-fe60-4acc-9744-66d8d2fb3782"}, "columns": ["y"]}], "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "d6b16de2-db4f-4bd5-b33c-71c50a091d1c"}, "type": "DataRange1d", "id": "d6b16de2-db4f-4bd5-b33c-71c50a091d1c"}, {"attributes": {"doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "f674a2f6-e917-4684-b877-3aa2fdd33dd5", "tags": []}, "type": "BasicTickFormatter", "id": "f674a2f6-e917-4684-b877-3aa2fdd33dd5"}, {"attributes": {"tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "e7944dd2-bbcb-435f-bc62-6da53efb1c83", "num_minor_ticks": 5}, "type": "BasicTicker", "id": "e7944dd2-bbcb-435f-bc62-6da53efb1c83"}, {"attributes": {"plot": {"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7"}, "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "dimension": 1, "ticker": {"type": "BasicTicker", "id": "e7944dd2-bbcb-435f-bc62-6da53efb1c83"}, "id": "40c58c15-7cdd-4f62-b8d9-bbb652749d47"}, "type": "Grid", "id": "40c58c15-7cdd-4f62-b8d9-bbb652749d47"}, {"attributes": {"geometries": [], "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "0ff5dd6f-4319-456a-ae3d-1f2b5c39b5c7"}, "type": "ToolEvents", "id": "0ff5dd6f-4319-456a-ae3d-1f2b5c39b5c7"}, {"attributes": {"plot": {"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7"}, "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "axis_label": "Petal Length", "formatter": {"type": "BasicTickFormatter", "id": "5f643ee8-3529-4327-b1b1-75d42814c38b"}, "ticker": {"type": "BasicTicker", "id": "a2a91543-d2f4-441b-bfcc-9c4d8f76273b"}, "id": "7a4cef60-fef8-418e-8dce-5735a632443a"}, "type": "LinearAxis", "id": "7a4cef60-fef8-418e-8dce-5735a632443a"}, {"attributes": {"plot": {"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7"}, "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "c66c8537-24d4-49a4-a901-fe51a63eed92"}, "type": "PreviewSaveTool", "id": "c66c8537-24d4-49a4-a901-fe51a63eed92"}, {"attributes": {"plot": {"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7"}, "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "axis_label": "Petal Width", "formatter": {"type": "BasicTickFormatter", "id": "f674a2f6-e917-4684-b877-3aa2fdd33dd5"}, "ticker": {"type": "BasicTicker", "id": "e7944dd2-bbcb-435f-bc62-6da53efb1c83"}, "id": "c7c97009-eca8-403a-825f-21fc45a7b994"}, "type": "LinearAxis", "id": "c7c97009-eca8-403a-825f-21fc45a7b994"}, {"attributes": {"plot": {"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7"}, "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "33f7029c-f9ae-42e5-8bea-1e031bbecf62"}, "type": "BoxZoomTool", "id": "33f7029c-f9ae-42e5-8bea-1e031bbecf62"}, {"attributes": {"plot": {"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7"}, "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "d7be6268-5bc5-4110-9d9e-8637501ac879"}, "type": "ResetTool", "id": "d7be6268-5bc5-4110-9d9e-8637501ac879"}, {"attributes": {"column_names": ["fill_color", "line_color", "x", "y"], "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "selected": [], "discrete_ranges": {}, "cont_ranges": {}, "data": {"line_color": ["red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue"], "x": [1.4, 1.4, 1.3, 1.5, 1.4, 1.7, 1.4, 1.5, 1.4, 1.5, 1.5, 1.6, 1.4, 1.1, 1.2, 1.5, 1.3, 1.4, 1.7, 1.5, 1.7, 1.5, 1.0, 1.7, 1.9, 1.6, 1.6, 1.5, 1.4, 1.6, 1.6, 1.5, 1.5, 1.4, 1.5, 1.2, 1.3, 1.4, 1.3, 1.5, 1.3, 1.3, 1.3, 1.6, 1.9, 1.4, 1.6, 1.4, 1.5, 1.4, 4.7, 4.5, 4.9, 4.0, 4.6, 4.5, 4.7, 3.3, 4.6, 3.9, 3.5, 4.2, 4.0, 4.7, 3.6, 4.4, 4.5, 4.1, 4.5, 3.9, 4.8, 4.0, 4.9, 4.7, 4.3, 4.4, 4.8, 5.0, 4.5, 3.5, 3.8, 3.7, 3.9, 5.1, 4.5, 4.5, 4.7, 4.4, 4.1, 4.0, 4.4, 4.6, 4.0, 3.3, 4.2, 4.2, 4.2, 4.3, 3.0, 4.1, 6.0, 5.1, 5.9, 5.6, 5.8, 6.6, 4.5, 6.3, 5.8, 6.1, 5.1, 5.3, 5.5, 5.0, 5.1, 5.3, 5.5, 6.7, 6.9, 5.0, 5.7, 4.9, 6.7, 4.9, 5.7, 6.0, 4.8, 4.9, 5.6, 5.8, 6.1, 6.4, 5.6, 5.1, 5.6, 6.1, 5.6, 5.5, 4.8, 5.4, 5.6, 5.1, 5.1, 5.9, 5.7, 5.2, 5.0, 5.2, 5.4, 5.1], "fill_color": ["red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "red", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "green", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue", "blue"], "y": [0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2, 1.4, 1.5, 1.5, 1.3, 1.5, 1.3, 1.6, 1.0, 1.3, 1.4, 1.0, 1.5, 1.0, 1.4, 1.3, 1.4, 1.5, 1.0, 1.5, 1.1, 1.8, 1.3, 1.5, 1.2, 1.3, 1.4, 1.4, 1.7, 1.5, 1.0, 1.1, 1.0, 1.2, 1.6, 1.5, 1.6, 1.5, 1.3, 1.3, 1.3, 1.2, 1.4, 1.2, 1.0, 1.3, 1.2, 1.3, 1.3, 1.1, 1.3, 2.5, 1.9, 2.1, 1.8, 2.2, 2.1, 1.7, 1.8, 1.8, 2.5, 2.0, 1.9, 2.1, 2.0, 2.4, 2.3, 1.8, 2.2, 2.3, 1.5, 2.3, 2.0, 2.0, 1.8, 2.1, 1.8, 1.8, 1.8, 2.1, 1.6, 1.9, 2.0, 2.2, 1.5, 1.4, 2.3, 2.4, 1.8, 1.8, 2.1, 2.4, 2.3, 1.9, 2.3, 2.5, 2.3, 1.9, 2.0, 2.3, 1.8]}, "id": "8515850a-fe60-4acc-9744-66d8d2fb3782"}, "type": "ColumnDataSource", "id": "8515850a-fe60-4acc-9744-66d8d2fb3782"}, {"attributes": {"plot": {"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7"}, "tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "5269f11b-cebb-42a8-910c-068e1d0ee01f"}, "type": "ResizeTool", "id": "5269f11b-cebb-42a8-910c-068e1d0ee01f"}, {"attributes": {"tags": [], "doc": "d802a8d3-727b-43d6-bef8-f133051c6a10", "id": "a8115598-9957-4dad-81be-0f8f03fab30e", "children": [{"subtype": "Figure", "type": "Plot", "id": "36b23184-e1d8-46bb-8c77-0e87f13dc2a7"}]}, "type": "PlotContext", "id": "a8115598-9957-4dad-81be-0f8f03fab30e"}];

Bokeh.$(function() {
    var modelid = "a8115598-9957-4dad-81be-0f8f03fab30e";
    var modeltype = "PlotContext";
    var elementid = "14c57239-c7da-4c0d-ac53-272e34eae54c";
    Bokeh.logger.info("Realizing plot:")
    Bokeh.logger.info(" - modeltype: PlotContext");
    Bokeh.logger.info(" - modelid: " + modelid);
    Bokeh.logger.info(" - elementid: " + elementid);
    Bokeh.load_models(all_models);
    var el = document.createElement("div");
    el.setAttribute("id", elementid);
    el.setAttribute("class", "plotdiv");
    document.documentElement.appendChild(el);
    var model = Bokeh.Collections(modeltype).get(modelid);
    var view = new model.default_view({model: model, el: '#' + elementid});
    Bokeh.index[modelid] = view;
});

@mattpap
Copy link
Contributor

mattpap commented Feb 2, 2015

Looking at jsdom's issue tracker, there will be a few more issues to resolve altogether.

@mattpap
Copy link
Contributor

mattpap commented Feb 2, 2015

If you run above code under PR #1797, you will get:

Bokeh: setting prefix to /
Bokeh: setting log level to: 'info'
Bokeh: Realizing plot:
Bokeh:  - modeltype: PlotContext
Bokeh:  - modelid: a8115598-9957-4dad-81be-0f8f03fab30e
Bokeh:  - elementid: 14c57239-c7da-4c0d-ac53-272e34eae54c

/home/mateusz/continuum/repo/bokeh/bokehjs/build/js/bokeh.js:20712
        this.ctx = this.canvas.getContext("2d");
                               ^
TypeError: Cannot call method 'getContext' of undefined
    at CanvasView.render (/home/mateusz/continuum/repo/bokeh/bokehjs/build/js/bokeh.js:20712:32)
    at PlotView.initialize (/home/mateusz/continuum/repo/bokeh/bokehjs/build/js/bokeh.js:40259:26)
    at PlotView.Backbone.View (/home/mateusz/continuum/repo/bokeh/bokehjs/build/js/bokeh.js:8249:21)
    at PlotView.ContinuumView (/home/mateusz/continuum/repo/bokeh/bokehjs/build/js/bokeh.js:9004:52)
    at new PlotView (/home/mateusz/continuum/repo/bokeh/bokehjs/build/js/bokeh.js:40226:47)
    at build_views (/home/mateusz/continuum/repo/bokeh/bokehjs/build/js/bokeh.js:13985:36)
    at PlotContextView.build_children (/home/mateusz/continuum/repo/bokeh/bokehjs/build/js/bokeh.js:31623:25)
    at PlotContextView.render (/home/mateusz/continuum/repo/bokeh/bokehjs/build/js/bokeh.js:31662:14)
    at PlotContextView.initialize (/home/mateusz/continuum/repo/bokeh/bokehjs/build/js/bokeh.js:31614:21)
    at PlotContextView.Backbone.View (/home/mateusz/continuum/repo/bokeh/bokehjs/build/js/bokeh.js:8249:21)

despite node-canvas being loaded. If you try to debug this, it will crash node.js (as mentioned in an earlier comment).

@bryevdv
Copy link
Member Author

bryevdv commented Feb 3, 2015

ping @tswicegood actually lets keep comments in the issue, as the current PR may not cover the entire discussion.

@tswicegood
Copy link
Contributor

This just popped up in my feed again because of the activity. FWIW, I would seriously consider browserify when you head down the route of moving to Node. I know @mattpap has some custom build tooling in place that relies on Require.js, but I believe the benefits of Browserify are pretty significant:

  • Uses Node/io.js's internal module loader CommonJS: this means no changes are necessary for code to run inside Node.
  • Tests can be run in a Node process rather than the browser. This should simplify testing logic.
  • Removes one indention layer (not as big of a deal, but they do add up).
  • CommonJS provides a more natural means of loading code -- I've never read a defense of define(["foo", "bar"], (foo, bar) ->… as a sane syntax.
  • Allows you to use CoffeeScript's object destructuring when loading code (think of it as from foo import bar).

And most importantly: Brings Bokeh and the new Anaconda Launcher platform together on the same build chain. You can see a full project written out using CommonJS + Browserify in this part of the tree (note that it's node-webkit, so nodeRequire is a hack to make sure we're talking to the Node process, not the rewritten one from Browserify).


I played around with switching to Browserify back last fall without a full development environment setup. I was able to get it to compile within an afternoon, though, as I said, I didn't have a dev environment setup so I'm not sure how much additional work would be necessary.

@bryevdv
Copy link
Member Author

bryevdv commented Feb 22, 2015

@tswicegood is this something you could devote a day or two to helping with sometime in the next month or two? I would love to come to LA and bang this out as well as some other server improvements, in a super-focused sprint.

@bryevdv
Copy link
Member Author

bryevdv commented Feb 22, 2015

To be clear, I think the current work should be merged right after 0.8.1 :)

@bryevdv bryevdv modified the milestones: 0.8.2, short-term Feb 22, 2015
@mattpap
Copy link
Contributor

mattpap commented Feb 23, 2015

My custom build isn't that big deal, I will figure this out. However, to note this, switching to browserify isn't going to help this issue. The problem we are dealing with here is that node.js libraries are just not mature enough to handle complex piece of code as bokehjs is.

@bryevdv
Copy link
Member Author

bryevdv commented Feb 23, 2015

@mattpap right I realize that, but it seems like a nice transition nonetheless. Regarding node.js and bokeh specifically, do you characterize things as completely hopeless at this point, or is there some useful subset that will work, or perhaps upstream contributions we could make?

@mattpap
Copy link
Contributor

mattpap commented Feb 23, 2015

I realize that, but it seems like a nice transition nonetheless.

I don't negate that. I just want make sure that in this issue we stay focused solving the actual problem.

do you characterize things as completely hopeless at this point

It's not hopeless. Maybe there is some workaround of jsdom's issues, or perhaps jsdom could be improved. I don't know node.js internals, so I can't say anything more right now. However, I think that it would be better to make bokehjs DOM independent, as much as possible. Then could use node-canvas directly.

@bryevdv
Copy link
Member Author

bryevdv commented Feb 23, 2015

I agree, let's hash out a plan of for that after this PR is merged (hopefully later today)

@tswicegood
Copy link
Contributor

@bryevdv sure. The next few weeks are a bit busy, but past that I should have some time. I'm going to be in Austin in late March it looks like, but if you wanted to come out before then we could bang it out.

@damianavila
Copy link
Contributor

Since #1797 was merged, do you want to continue further discussion here? or can this one be closed?

@mattpap
Copy link
Contributor

mattpap commented Feb 27, 2015

@damianavila, #1797 doesn't resolve this issue (just makes the first step towards fixing it).

@damianavila
Copy link
Contributor

yes... I know... this is why I asked if you want to keep the discussion centralized here... ok, I will label #1797 properly, thanks!

@bryevdv bryevdv removed this from the 0.8.2 milestone Mar 26, 2015
@bryevdv bryevdv modified the milestones: 0.9, 0.8.2 Mar 26, 2015
@bryevdv bryevdv modified the milestones: short-term, 0.9 Apr 22, 2015
@bryevdv
Copy link
Member Author

bryevdv commented Jul 11, 2015

@mattpap I'd like your opinion on the following question:

How feasible would it be to:

  • patch canvas to simply record what actions would be taken, without actually making real canvas drawing calls (should be easy)

and

  • run bokeh plots "enough" to get back the recorded "log" of canvas actions out?

This would be useful on two fronts:

  • it would make our renderers JS unit-testable without image diffs (we should still make image diffs, of course)
  • It would be trivial to make a pycairo command line utility to generate static output from the canvas "log" (or possibly even SVG directly, now that I think about it)

All of these things can be ignored / don't need to function:

  • tools
  • dom layout
  • events

Did the problems en encountered intersect with the smaller subset of functionality we could need ? Could they be worked around?

@mattpap
Copy link
Contributor

mattpap commented Jul 14, 2015

Creating a log of actions should be easy indeed, but I'm worried it may be too big for any practical purpose. Unit testing seems an interesting idea, but it depends whether this approach will be actually faster and more robust than image diff.

@mattpap
Copy link
Contributor

mattpap commented Jul 14, 2015

It would be trivial to make a pycairo command line utility to generate static output from the canvas

I'm not so sure about that. You have to make sure that pycairo's canvas semantics match exactly HTML5 canvas. Otherwise, you would have to implement a layer on top of pycairo. Note that there is already such effort for node.js, i.e. node-canvas.

@bryevdv
Copy link
Member Author

bryevdv commented Jul 14, 2015

I'm not so sure about that. You have to make sure that pycairo's canvas semantics match exactly HTML5 canvas. Otherwise, you would have to implement a layer on top of pycairo. Note that there is already such effort for node.js, i.e. node-canvas.

For sure, we should investigate whether JS things have moved on since the last time we looked. I have used cairo pretty extensively in the past, which is why I am thinking of it. The semantics are definitely similar enough that a translation from one to the other would be straightforward, if not trivial.

@bryevdv
Copy link
Member Author

bryevdv commented Jul 17, 2015

@mattpap also I am suggesting adding the kinds of unit tests in addition to the image diff tests. Then we could have some quick jobs across platforms that do nothing but unit tests, and another job that does nothing but image diff tests, and perhaps by splitting things up we can achieve an overall time reduction.

@tobyhodges
Copy link
Contributor

Hi all. Is headless output as vector graphic formats something that is likely to be included in a release in the foreseeable future, e.g. in 0.11? I am about to start working on a new project that this would be fairly vital to, and I'd love to be able to commit to using Bokeh for it.

@bryevdv
Copy link
Member Author

bryevdv commented Oct 23, 2015

It's definitely not going to be in 0.11.

We are pushing through two big architectural efforts (the server re-write in tornado, and splitting up BokehJS) as well as some larger features that are immediately relevant to some current engagements (Annotations, GIS and tile rendering). Static output is an important priority, unfortunately there are lots of important priorities, and it's also a very technically challenging one as well. That said, splitting BokehJS and into more manageable pieces will help towards being able to run parts of it in node.sat , and it's also possible node.js and node-canvas have developed further in the mean time as well. @mattpap do you have any notion of recent developments that might make this easier/better now?

@mattpap
Copy link
Contributor

mattpap commented Oct 23, 2015

do you have any notion of recent developments that might make this easier/better now?

Currently not, but I'm giving this another try.

@mattpap
Copy link
Contributor

mattpap commented Sep 21, 2016

@bryevdv, I'm favor of closing this issue as resolved, at least per its title. bokehjs and node.js integration is fairly reliable since PR #5129. As commented in that PR, bokehjs shouldn't assume anything about the environment, so it shouldn't depend neither on jsdom nor node-canvas. Further discussion should be continued in issue #538. An additional bundle is needed on top of bokehjs. However, I doubt bokehjs will be ever able to render static plots reliably in node.js. I think we should go ahead with headless chromium or similar. In such case, current bokehjs-node.js integration is sufficient.

@bryevdv bryevdv modified the milestones: 0.12.3, short-term Sep 21, 2016
@bryevdv
Copy link
Member Author

bryevdv commented Sep 21, 2016

sounds good to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants