Methos
Methos

Reputation: 14344

Creating a line with an arrow in React

A line with arrow is created using , elements as shown in the example below(not my code): http://jsfiddle.net/m1erickson/9aCsJ/

I tried to convert it to a React component as follows: http://jsfiddle.net/kdgqmt55/3/

But all I see is a red line and no arrow head.

Is this because marker or defs elements are unrecognized by React runtime?

(Code to satisfy Stackoverflow's JSFiddle condition:

React.render(<Arrow start={{x:0, y:0}} stop={{x:400, y:400}} />,
                                       $("#my-arrow").get(0)
                                       );  

)

Upvotes: 0

Views: 5089

Answers (1)

noveyak
noveyak

Reputation: 3300

This is an unfortunate aspect of using React to render SVG elements. They whitelist a bunch of attributes and attributes that are not on the list are dropped so you are losing a bunch of your markerWidth, markerHeight, and many other attributes.

https://facebook.github.io/react/docs/tags-and-attributes.html

There is discussion about fixing this here https://github.com/facebook/react/issues/140

For now, for attributes that are not defined you can do put them in componentDidMount. (Added a couple to demonstrate but didn't fully fix the example)

var Arrow = React.createClass({
       componentDidMount: function(){
           var markerNode = React.findDOMNode(this.refs.marker)
           var markerEndNode = React.findDOMNode(this.refs.markerEndNode)

           markerNode.setAttribute('markerWidth', 13)
           markerNode.setAttribute('markerHeight', 13)
           markerNode.setAttribute('refx', 2)
           markerNode.setAttribute('refy', 6)
       },
       render: function() {
            var style = {
                position: "absolute",
                zIndex: 200,
            };

            path_d = "M" + this.props.start.x + "," + this.props.start.y + " "
            path_d += "L" + this.props.stop.x + "," + this.props.stop.y

            return (
                <svg width="300" height="100" style={style} >
                    <defs>
                        <marker ref="marker" id="arrow">
                        <path d="M2,1 L2,10 L10,6 L2,2" style={{fill:"red"}} />
                        </marker>
                    </defs>

                <path ref="markerEndNode" d="M30,150 L100,50"
                    style={{stroke:"red", strokeWidth: "1.25px", fill: "none"}}
                />
            </svg>);
        },
    });

Upvotes: 3

Related Questions