_renderGraph = this._renderGraph.bind(this); } componentDidMount() { if (this.props.graph) { this._renderGraph(this.refs.container, this.props.graph); } } shouldComponentUpdate(nextProps) { return this.props.graph != nextProps.graph; } componentDidUpdate() { if (this.props.graph) { this._renderGraph(this.refs.container, this.props.graph); } } componentWillUnmount() { if (this.state.zoom) { this.state.zoom.on("zoom", null); } } _renderGraph(container, { nodes, edges }) { if (!container.firstChild) { const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svg.setAttribute("id", "graph-svg"); svg.setAttribute("xlink", "http://www.w3.org/1999/xlink"); svg.style.width = "100%"; svg.style.height = "100%"; const target = document.createElementNS( "http://www.w3.org/2000/svg", "g" ); target.setAttribute("id", "graph-target"); target.style.width = "100%"; target.style.height = "100%"; svg.appendChild(target); container.appendChild(svg); } const graph = new dagreD3.Digraph(); for (let i = 0; i < nodes.length; i++) { graph.addNode(nodes[i].id, { id: nodes[i].id, label: stringifyLabel(nodes[i].label, nodes[i].id), }); } for (let i = 0; i < edges.length; i++) { graph.addEdge(null, edges[i].from, edges[i].to, { label: edges[i].name, }); } const renderer = new dagreD3.Renderer(); renderer.drawNodes(); renderer.drawEdgePaths(); const svg = d3.select("#graph-svg"); const target = d3.select("#graph-target"); let zoom = this.state.zoom; if (!zoom) { zoom = d3.behavior.zoom().on("zoom", function () { target.attr( "transform", `translate(${d3.event.translate}) scale(${d3.event.scale})` ); }); svg.call(zoom); this.setState({ zoom }); } const { translate, scale } = GRAPH_DEFAULTS; zoom.scale(scale); zoom.translate(translate); target.attr("transform", `translate(${translate}) scale(${scale})`); const layout = dagreD3.layout(); renderer.layout(layout).run(graph, target); } render() { let contents; if (this.props.graph) { // Let the componentDidMount or componentDidUpdate method draw the graph // with DagreD3. We just provide the container for the graph here. contents = dom.div({ ref: "container", style: { flex: 1, height: "100%", width: "100%", }, }); } else { contents = dom.div( { id: "shortest-paths-select-node-msg", }, L10N.getStr("shortest-paths.select-node") ); } return dom.div( { id: "shortest-paths", className: "vbox", }, dom.label( { id: "shortest-paths-header", className: "header", }, L10N.getStr("shortest-paths.header") ), contents ); } } module.exports = ShortestPaths; PK