UNPKG

dc.graph

Version:

Graph visualizations integrated with crossfilter and dc.js

104 lines (101 loc) 3.63 kB
var _workers = {}; var NUMBER_RESULTS = 3; function create_worker(layoutAlgorithm) { if(!_workers[layoutAlgorithm]) { var worker = _workers[layoutAlgorithm] = { worker: new Worker(script_path() + 'dc.graph.' + layoutAlgorithm + '.worker.js'), layouts: {} }; worker.worker.onmessage = function(e) { var layoutId = e.data.layoutId; if(!worker.layouts[layoutId]) throw new Error('layoutId "' + layoutId + '" unknown!'); var engine = worker.layouts[layoutId].getEngine(); if(e.data.args.length > NUMBER_RESULTS && engine.processExtraWorkerResults) engine.processExtraWorkerResults.apply(engine, e.data.args.slice(NUMBER_RESULTS)); worker.layouts[layoutId].dispatch()[e.data.response].apply(null, e.data.args); }; } return _workers[layoutAlgorithm]; } dc_graph.webworker_layout = function(layoutEngine) { var _tick, _done, _dispatch = d3.dispatch('init', 'start', 'tick', 'end'); var _worker = create_worker(layoutEngine.layoutAlgorithm()); var engine = {}; _worker.layouts[layoutEngine.layoutId()] = engine; engine.parent = function(parent) { if(layoutEngine.parent) layoutEngine.parent(parent); }; engine.init = function(options) { options = layoutEngine.optionNames().reduce( function(options, option) { options[option] = layoutEngine[option](); return options; }, options); if(layoutEngine.propagateOptions) layoutEngine.propagateOptions(options); _worker.worker.postMessage({ command: 'init', args: { layoutId: layoutEngine.layoutId(), options: options } }); return this; }; engine.data = function(graph, nodes, edges, clusters, constraints) { _worker.worker.postMessage({ command: 'data', args: { layoutId: layoutEngine.layoutId(), graph: graph, nodes: nodes, edges: edges, clusters: clusters, constraints: constraints } }); }; engine.start = function() { _worker.worker.postMessage({ command: 'start', args: { layoutId: layoutEngine.layoutId() } }); }; engine.stop = function() { _worker.worker.postMessage({ command: 'stop', args: { layoutId: layoutEngine.layoutId() } }); return this; }; // stopgap while layout options are still on diagram engine.getEngine = function() { return layoutEngine; }; // somewhat sketchy - do we want this object to be transparent or not? var passthroughs = ['layoutAlgorithm', 'populateLayoutNode', 'populateLayoutEdge', 'rankdir', 'ranksep']; passthroughs.concat(layoutEngine.optionNames(), layoutEngine.passThru ? layoutEngine.passThru() : []).forEach(function(name) { engine[name] = function() { var ret = layoutEngine[name].apply(layoutEngine, arguments); return arguments.length ? this : ret; }; }); engine.on = function(event, f) { if(arguments.length === 1) return _dispatch.on(event); _dispatch.on(event, f); return this; }; engine.dispatch = function() { return _dispatch; }; return engine; };