我试图在React Js中为NLP / POS-tagger项目创建一个解析器树.我发现GoJs提供了一个很酷的解析器树
GoJs-parser-tree,但是我找不到react js实现的文档.我尝试了一些例子,但我无法使用它反应继承我的代码,我需要在反应中使用它
<!DOCTYPE html> <html> <head> <title>Parse Tree</title> <Meta name="description" content="A collapsible tree layout with all of the leaf nodes at the same layer." /> <!-- Copyright 1998-2016 by Northwoods Software Corporation. --> <Meta charset="UTF-8"> <script src="go.js"></script> <link href="../assets/css/goSamples.css" rel="stylesheet" type="text/css" /> <!-- you don't need to use this --> <script src="goSamples.js"></script> <!-- this is only for the GoJS Samples framework --> <script id="code"> function init() { if (window.goSamples) goSamples(); // init for these samples -- you don't need to call this var $= go.GraphObject.make; // for conciseness in defining templates myDiagram = $(go.Diagram,"myDiagramDiv",{ allowCopy: false,allowDelete: false,allowMove: false,initialContentAlignment: go.Spot.Center,initialAutoScale: go.Diagram.Uniform,layout: $(FlatTreeLayout,// custom Layout,defined below { angle: 90,compaction: go.TreeLayout.CompactionNone }),"undoManager.isEnabled": true }); myDiagram.nodeTemplate = $(go.Node,"Vertical",{ selectionObjectName: "BODY" },$(go.Panel,"Auto",{ name: "BODY" },$(go.Shape,"RoundedRectangle",new go.Binding("fill"),new go.Binding("stroke")),$(go.TextBlock,{ font: "bold 12pt Arial,sans-serif",margin: new go.Margin(4,2,2) },new go.Binding("text")) ),// this is underneath the "BODY" { height: 15 },// always this height,even if the TreeExpanderButton is not visible $("TreeExpanderButton") ) ); myDiagram.linkTemplate = $(go.Link,{ strokeWidth: 1.5 })); // set up the nodeDataArray,describing each part of the sentence var nodeDataArray = [ { key: 1,text: "Sentence",fill: "#f68c06",stroke: "#4d90fe" },{ key: 2,text: "NP",stroke: "#4d90fe",parent: 1 },{ key: 3,text: "DT",fill: "#ccc",parent: 2 },{ key: 4,text: "A",fill: "#f8f8f8",parent: 3 },{ key: 5,text: "JJ",{ key: 6,text: "rare",parent: 5 },{ key: 7,{ key: 8,text: "black",parent: 7 },{ key: 9,text: "NN",{ key: 10,text: "squirrel",parent: 9 },{ key: 11,text: "VP",{ key: 12,text: "VBZ",parent: 11 },{ key: 13,text: "has",parent: 12 },{ key: 14,{ key: 15,text: "VBN",parent: 14 },{ key: 16,text: "become",parent: 15 },{ key: 17,{ key: 18,parent: 17 },{ key: 19,parent: 18 },{ key: 20,text: "a",parent: 19 },{ key: 21,{ key: 22,text: "regular",parent: 21 },{ key: 23,{ key: 24,text: "visitor",parent: 23 },{ key: 25,text: "PP",{ key: 26,text: "TO",parent: 25 },{ key: 27,text: "to",parent: 26 },{ key: 28,{ key: 29,parent: 28 },{ key: 30,parent: 29 },{ key: 31,{ key: 32,text: "suburban",parent: 31 },{ key: 33,{ key: 34,text: "garden",parent: 33 },{ key: 35,text: ".",{ key: 36,parent: 35 } ] // create the Model with data for the tree,and assign to the Diagram myDiagram.model = $(go.TreeModel,{ nodeDataArray: nodeDataArray }); } // Customize the TreeLayout to position all of the leaf nodes at the same vertical Y position. function FlatTreeLayout() { go.TreeLayout.call(this); // call base constructor } go.Diagram.inherit(FlatTreeLayout,go.TreeLayout); // This assumes the TreeLayout.angle is 90 -- growing downward /** @override */ FlatTreeLayout.prototype.commitLayout = function() { go.TreeLayout.prototype.commitLayout.call(this); // call base method first // find maximum Y position of all Nodes var y = -Infinity; this.network.vertexes.each(function(v) { y = Math.max(y,v.node.position.y); }); // move down all leaf nodes to that Y position,but keeping their X position this.network.vertexes.each(function(v) { var node = v.node; if (node.isTreeLeaf) { node.position = new go.Point(node.position.x,y); } }); }; // end FlatTreeLayout </script> </head> <body onload="init()"> <div id="sample"> <h3>GoJS Parse Tree</h3> <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:500px"></div> <p>A <em>parse tree</em> is an ordered,rooted tree representing the structure of a sentence,broken down to parts-of-speech.</p> <p> This diagram uses a custom <a>TreeLayout</a> called <b>FlatTreeLayout</b> that places all leaf nodes at the same Y position. It also makes use of a <b>TreeExpanderButton</b> on the node template. See the <a href="../intro/buttons.html">Intro page on Buttons</a> for more GoJS button information. </p> <p> The abbreviations used in this diagram are: <ul> <li><b>NP</b>,a noun phrase</li> <li><b>VP</b>,a verb phrase</li> <li><b>PP</b>,a prepositional phrase</li> <li><b>DT</b>,a determiner</li> <li><b>JJ</b>,an adjective</li> <li><b>NN</b>,a common noun</li> <li><b>VBZ</b>,a third person singular present verb</li> <li><b>VBN</b>,a past participle verb</li> </ul> </p> </div> </body> </html>
这个我尝试使用它时得到的代码作出反应
import React,{Component} from 'react'; import go from 'gojs'; const goObj = go.GraphObject.make; export default class GoJs extends Component { constructor (props) { super (props); this.renderCanvas = this.renderCanvas.bind (this); this.state = {myModel: null,myDiagram: null} } renderCanvas () { let model = goObj (go.TreeModel); let diagram = goObj (go.Diagram,this.refs.goJsDiv,{initialContentAlignment: go.Spot.Center}); this.setState({myModel: model,myDiagram: diagram},() => { model.nodeDataArray = this.props.data; diagram.model = model; this.setState({myModel: model,myDiagram: diagram}); } ); } componentDidMount () { this.renderCanvas (); } componentWillUpdate (prevProps) { if (this.props.data !== prevProps.data) { console.log ('Updating'); const model = this.state.myModel; const diagram = this.state.myDiagram; model.nodeDataArray = this.props.data; diagram.model = model; this.setState({myModel: model,myDiagram: diagram}); } } render () { return <div ref="goJsDiv" style={{'width': '500px','height': '500px','backgroundColor': '#DAE4E4'}}></div>; } } GoJs.propTypes = { data: React.PropTypes.string.isrequired }; GoJs.defaultProps = { data: '[]' };
我无法弄清楚什么是丢失的,而我从这里得到的输出是一团糟.
解决方法
在这里和那里花了几个小时更改代码后,我设法制作了所需的内容,这是我的最终代码
import React,myDiagram: null} } renderCanvas () { function FlatTreeLayout () { go.TreeLayout.call(this); // call base constructor } go.Diagram.inherit(FlatTreeLayout,go.TreeLayout); // This assumes the TreeLayout.angle is 90 -- growing downward /** @override */ FlatTreeLayout.prototype.commitLayout = function () { go.TreeLayout.prototype.commitLayout.call(this); // call base method first // find maximum Y position of all Nodes var y = -Infinity; this.network.vertexes.each(function(v) { y = Math.max(y,v.node.position.y); }); // move down all leaf nodes to that Y position,but keeping their X position this.network.vertexes.each(function(v) { var node = v.node; if (node.isTreeLeaf) { node.position = new go.Point(node.position.x,y); } }); }; let model = goObj (go.TreeModel); let diagram = goObj (go.Diagram,{ allowCopy: false,layout: goObj(FlatTreeLayout,defined below { angle: 90,"undoManager.isEnabled": true }); diagram.nodeTemplate = goObj(go.Node,goObj(go.Panel,goObj(go.Shape,goObj(go.TextBlock,new go.Binding("text")) ),// this is underneath the "BODY" { height: 15 },even if the TreeExpanderButton is not visible goObj("TreeExpanderButton") ) ); diagram.linkTemplate = goObj(go.Link,{ strokeWidth: 1.5 })); this.setState({myModel: model,myDiagram: diagram}); } ); } componentDidMount () { this.renderCanvas (); } componentWillUpdate (prevProps) { if (this.props.data !== prevProps.data) { console.log ('Updating'); const model = this.state.myModel; const diagram = this.state.myDiagram; model.nodeDataArray = this.props.data; diagram.model = model; this.setState({myModel: model,'backgroundColor': '#DAE4E4'}}></div>; } } GoJs.propTypes = { data: React.PropTypes.string.isrequired }; GoJs.defaultProps = { data: '[]' };
由于它是一个dum组件,我们必须通过props从父组件传递数据.
来自父组件
render(){ return( <div> <PTagBox data={nodeDataArray}/> </div> ); }
其中PTagBox是哑或子组件