From 93c8c9ebed758817248ece1c5685c001f4375f85 Mon Sep 17 00:00:00 2001 From: Lutz Roeder Date: Tue, 21 Dec 2021 13:08:27 -0500 Subject: [PATCH] Update view-grapher.js (#68) --- source/view-grapher.js | 41 +++++-- source/view.js | 235 +++++++++++++++++++++-------------------- 2 files changed, 152 insertions(+), 124 deletions(-) diff --git a/source/view-grapher.js b/source/view-grapher.js index 92cbff130f7..da8a732a5eb 100644 --- a/source/view-grapher.js +++ b/source/view-grapher.js @@ -281,13 +281,9 @@ grapher.Node.Header = class { } add(id, classList, content, tooltip, handler) { - this._items.push({ - id: id, - classList: classList, - content: content, - tooltip: tooltip, - handler: handler - }); + const item = new grapher.Node.Header.Item(id, classList, content, tooltip, handler); + this._items.push(item); + return item; } build(document, parentElement) { @@ -314,8 +310,10 @@ grapher.Node.Header = class { if (item.id) { element.setAttribute('id', item.id); } - if (item.handler) { - element.addEventListener('click', item.handler); + if (item.events.click) { + element.addEventListener('click', () => { + item.raise('click'); + }); } if (item.tooltip) { const titleElement = this.createElement('title'); @@ -414,6 +412,31 @@ grapher.Node.Header = class { } }; +grapher.Node.Header.Item = class { + + constructor(id, classList, content, tooltip, handler) { + this.id = id; + this.classList = classList; + this.content = content; + this.tooltip = tooltip; + this.handler = handler; + this.events = {}; + } + + on(event, callback) { + this.events[event] = this.events[event] || []; + this.events[event].push(callback); + } + + raise(event, data) { + if (this.events && this.events[event]) { + for (const callback of this.events[event]) { + callback(this, data); + } + } + } +}; + grapher.Node.List = class { constructor() { diff --git a/source/view.js b/source/view.js index 900cc7c1970..1104e96dc11 100644 --- a/source/view.js +++ b/source/view.js @@ -555,107 +555,7 @@ view.View = class { } const viewGraph = new view.Graph(this, model, groups, options); - - const clusters = new Set(); - const clusterParentMap = new Map(); - - if (groups) { - for (const node of nodes) { - if (node.group) { - const path = node.group.split('/'); - while (path.length > 0) { - const name = path.join('/'); - path.pop(); - clusterParentMap.set(name, path.join('/')); - } - } - } - } - - for (const input of graph.inputs) { - const viewInput = viewGraph.createInput(input); - for (const argument of input.arguments) { - viewGraph.createArgument(argument).from(viewInput); - } - } - - for (const node of nodes) { - - const viewNode = viewGraph.createNode(node); - - const inputs = node.inputs; - for (const input of inputs) { - for (const argument of input.arguments) { - if (argument.name != '' && !argument.initializer) { - viewGraph.createArgument(argument).to(viewNode); - } - } - } - let outputs = node.outputs; - if (node.chain && node.chain.length > 0) { - const chainOutputs = node.chain[node.chain.length - 1].outputs; - if (chainOutputs.length > 0) { - outputs = chainOutputs; - } - } - for (const output of outputs) { - for (const argument of output.arguments) { - if (!argument) { - throw new view.Error("Invalid null argument in '" + model.identifier + "'."); - } - if (argument.name != '') { - viewGraph.createArgument(argument).from(viewNode); - } - } - } - - if (node.controlDependencies && node.controlDependencies.length > 0) { - for (const argument of node.controlDependencies) { - viewGraph.createArgument(argument).to(viewNode, true); - } - } - - const createCluster = function(name) { - if (!clusters.has(name)) { - viewGraph.setNode({ name: name, rx: 5, ry: 5}); - clusters.add(name); - const parent = clusterParentMap.get(name); - if (parent) { - createCluster(parent); - viewGraph.setParent(name, parent); - } - } - }; - - if (groups) { - let groupName = node.group; - if (groupName && groupName.length > 0) { - if (!clusterParentMap.has(groupName)) { - const lastIndex = groupName.lastIndexOf('/'); - if (lastIndex != -1) { - groupName = groupName.substring(0, lastIndex); - if (!clusterParentMap.has(groupName)) { - groupName = null; - } - } - else { - groupName = null; - } - } - if (groupName) { - createCluster(groupName); - viewGraph.setParent(viewNode.name, groupName); - } - } - } - } - - for (const output of graph.outputs) { - const viewOutput = viewGraph.createOutput(output); - for (const argument of output.arguments) { - viewGraph.createArgument(argument).to(viewOutput); - } - } + viewGraph.add(graph); // Workaround for Safari background drag/zoom issue: // https://stackoverflow.com/questions/40887193/d3-js-zoom-is-not-working-with-mousewheel-in-safari @@ -965,12 +865,113 @@ view.Graph = class extends grapher.Graph { return value; } - build(document, originElement) { + add(graph) { + const clusters = new Set(); + const clusterParentMap = new Map(); + const groups = graph.groups; + if (groups) { + for (const node of graph.nodes) { + if (node.group) { + const path = node.group.split('/'); + while (path.length > 0) { + const name = path.join('/'); + path.pop(); + clusterParentMap.set(name, path.join('/')); + } + } + } + } + for (const input of graph.inputs) { + const viewInput = this.createInput(input); + for (const argument of input.arguments) { + this.createArgument(argument).from(viewInput); + } + } + + for (const node of graph.nodes) { + + const viewNode = this.createNode(node); + + const inputs = node.inputs; + for (const input of inputs) { + for (const argument of input.arguments) { + if (argument.name != '' && !argument.initializer) { + this.createArgument(argument).to(viewNode); + } + } + } + let outputs = node.outputs; + if (node.chain && node.chain.length > 0) { + const chainOutputs = node.chain[node.chain.length - 1].outputs; + if (chainOutputs.length > 0) { + outputs = chainOutputs; + } + } + for (const output of outputs) { + for (const argument of output.arguments) { + if (!argument) { + throw new view.Error("Invalid null argument in '" + model.identifier + "'."); + } + if (argument.name != '') { + this.createArgument(argument).from(viewNode); + } + } + } + + if (node.controlDependencies && node.controlDependencies.length > 0) { + for (const argument of node.controlDependencies) { + this.createArgument(argument).to(viewNode, true); + } + } + + const createCluster = function(name) { + if (!clusters.has(name)) { + this.setNode({ name: name, rx: 5, ry: 5}); + clusters.add(name); + const parent = clusterParentMap.get(name); + if (parent) { + createCluster(parent); + this.setParent(name, parent); + } + } + }; + + if (groups) { + let groupName = node.group; + if (groupName && groupName.length > 0) { + if (!clusterParentMap.has(groupName)) { + const lastIndex = groupName.lastIndexOf('/'); + if (lastIndex != -1) { + groupName = groupName.substring(0, lastIndex); + if (!clusterParentMap.has(groupName)) { + groupName = null; + } + } + else { + groupName = null; + } + } + if (groupName) { + createCluster(groupName); + this.setParent(viewNode.name, groupName); + } + } + } + } + + for (const output of graph.outputs) { + const viewOutput = this.createOutput(output); + for (const argument of output.arguments) { + this.createArgument(argument).to(viewOutput); + } + } + } + + build(document, originElement) { for (const argument of this._arguments.values()) { argument.build(); } - super.build(document, originElement); } }; @@ -999,7 +1000,6 @@ view.Node = class extends grapher.Node { } _add(node) { - const header = this.header(); const styles = [ 'node-item-type' ]; const type = node.type; @@ -1013,18 +1013,15 @@ view.Node = class extends grapher.Node { } const content = this.context.view.options.names && (node.name || node.location) ? (node.name || node.location) : type.name.split('.').pop(); const tooltip = this.context.view.options.names && (node.name || node.location) ? type.name : (node.name || node.location); - header.add(null, styles, content, tooltip, () => { - this.context.view.showNodeProperties(node, null); - }); + const title = header.add(null, styles, content, tooltip); + title.on('click', () => this.context.view.showNodeProperties(node, null)); if (node.type.nodes) { - header.add(null, styles, '\u0192', 'Show Function Definition', () => { - this.context.view.pushGraph(node.type); - }); + const definition = header.add(null, styles, '\u0192', 'Show Function Definition'); + definition.on('click', () => this.context.view.pushGraph(node.type)); } if (node.nodes) { - header.add(null, styles, '+', null, () => { - // debugger; - }); + this._expand = header.add(null, styles, '+', null); + this._expand.on('click', () => this.toggle()); } const initializers = []; let hiddenInitializers = false; @@ -1107,6 +1104,12 @@ view.Node = class extends grapher.Node { this._add(node.inner); } } + + toggle() { + // this._expand.content = '-'; + // this._graph = new view.Graph(this.context.view, this.context.model, false, {}); + // this._graph.add(this.value); + } }; view.Input = class extends grapher.Node { @@ -1122,7 +1125,8 @@ view.Input = class extends grapher.Node { name = name.split('/').pop(); } const header = this.header(); - header.add(null, [ 'graph-item-input' ], name, types, () => this.context.view.showModelProperties()); + const title = header.add(null, [ 'graph-item-input' ], name, types); + title.on('click', () => this.context.view.showModelProperties()); this.id = 'input-' + (name ? 'name-' + name : 'id-' + (view.Input.counter++).toString()); } @@ -1151,7 +1155,8 @@ view.Output = class extends grapher.Node { name = name.split('/').pop(); } const header = this.header(); - header.add(null, [ 'graph-item-output' ], name, types, () => this.context.view.showModelProperties()); + const title = header.add(null, [ 'graph-item-output' ], name, types); + title.on('click', () => this.context.view.showModelProperties()); } get inputs() {