` that it rotates and positions
6 | where it needs to be.
7 |
8 | ## Why
9 |
10 | Sometimes, you want to draw a line in your page (mostly, a line that is linked to 2 items that can move for instance), not using fancy stuff. A `
` is not a fancy stuff but requires some mathematics to handle the position and rotation properly from 2 coordinates.
11 |
12 | ## Install
13 |
14 | ```shell
15 | npm install --save react-line
16 | ```
17 |
18 | ## Props
19 |
20 | You need to provide 4 coordinates to draw a line which are the props of the
21 | component :
22 |
23 | ```javascript
24 | static propTypes = {
25 | from: React.PropTypes.shape({
26 | x: React.PropTypes.number.isRequired,
27 | y: React.PropTypes.number.isRequired,
28 | }),
29 | to: React.PropTypes.shape({
30 | x: React.PropTypes.number.isRequired,
31 | y: React.PropTypes.number.isRequired,
32 | }),
33 | style: React.PropTypes.string
34 | }
35 | ```
36 |
37 | `style` is optional and is the css style you want to apply on the line.
38 | The default is `1px solid black`.
39 |
40 | ## Usage
41 |
42 | ```javascript
43 |
48 | ```
49 |
50 | An octogon :
51 |
52 | 
53 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default class Line extends React.Component {
4 |
5 | static propTypes = {
6 | from: React.PropTypes.shape({
7 | x: React.PropTypes.number.isRequired,
8 | y: React.PropTypes.number.isRequired,
9 | }),
10 | to: React.PropTypes.shape({
11 | x: React.PropTypes.number.isRequired,
12 | y: React.PropTypes.number.isRequired,
13 | }),
14 | style: React.PropTypes.string
15 | };
16 |
17 | render() {
18 | let from = this.props.from;
19 | let to = this.props.to;
20 | if (to.x < from.x) {
21 | from = this.props.to;
22 | to = this.props.from;
23 | }
24 |
25 | const len = Math.sqrt(Math.pow(from.x - to.x, 2) + Math.pow(from.y - to.y, 2));
26 | const angle = Math.atan((to.y - from.y) / (to.x - from.x));
27 |
28 | const style = {
29 | position: 'absolute',
30 | transform: `translate(${from.x - .5 * len * (1 - Math.cos(angle))}px, ${from.y + .5 * len * Math.sin(angle)}px) rotate(${angle}rad)`,
31 | width: `${len}px`,
32 | height: `${0}px`,
33 | borderBottom: this.props.style || '1px solid black'
34 | };
35 |
36 | return
;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/octogon.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sderosiaux/react-line/9848b74cc298a7b30aa5b48a98064d4437b4e010/octogon.PNG
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-line",
3 | "version": "1.0.2",
4 | "description": "Provide a React component to draw a line",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/chtefi/react-line.git"
12 | },
13 | "keywords": [
14 | "react",
15 | "line",
16 | "chart",
17 | "dataviz",
18 | "link"
19 | ],
20 | "author": "Stéphane D.",
21 | "license": "MIT",
22 | "bugs": {
23 | "url": "https://github.com/chtefi/react-line/issues"
24 | },
25 | "homepage": "https://github.com/chtefi/react-line#readme",
26 | "dependencies": {
27 | "react": "^0.13.3"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Line from './index';
3 |
4 | const LINE_STYLE = '2px dashed blue';
5 |
6 | // Octogon
7 | const points = [
8 | { x: 60, y: 0 },
9 | { x: 120, y: 0 },
10 | { x: 180, y: 60 },
11 | { x: 180, y: 120 },
12 | { x: 120, y: 180 },
13 | { x: 60, y: 180 },
14 | { x: 0, y: 120 },
15 | { x: 0, y: 60 },
16 | { x: 60, y: 0 },
17 | ].reduce((lines, p, index, arr) => {
18 | if (index === 0) return lines;
19 | return lines.concat({
20 | x1: arr[index-1].x,
21 | y1: arr[index-1].y,
22 | x2: p.x,
23 | y2: p.y
24 | });
25 | }, []);
26 |
27 | export default class App extends React.Component {
28 | render() {
29 | return (
30 |
31 | {
32 | points.map((p, i) => )
38 | }
39 |
40 | );
41 | }
42 | }
43 |
--------------------------------------------------------------------------------