Skip to content

Commit 39b8937

Browse files
authored
Merge pull request #17 from zsjjs/v1.0.5
V1.0.5
2 parents 9c6960b + 279359c commit 39b8937

File tree

10 files changed

+130
-36
lines changed

10 files changed

+130
-36
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
![gzip size](http://img.badgesize.io/https://npmcdn.com/react-field-mapping/dist/fieldmapping.js?compression=gzip)
66
[![license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://raw.githubusercontent.com/zsjjs/react-field-mapping/master/LICENSE)
77

8-
#### 基于react的表字段映射组件
8+
#### 关系映射组件
99

1010
### View the <a href="https://codepen.io/godIsMe/pen/xvgYdx">Demo</a> and its <a href="https://github.com/zsjjs/react-field-mapping/blob/master/example/test.js">source</a> for more.
1111

@@ -79,7 +79,7 @@
7979
<td colspan="2">isSort</td>
8080
<td>是否开启字段排序</td>
8181
<td align="center">boolean</td>
82-
<td align="center">true</td>
82+
<td align="center">false</td>
8383
</tr>
8484
<tr>
8585
<td colspan="2">edit</td>

example/test.html

Lines changed: 2 additions & 1 deletion
Large diffs are not rendered by default.

example/test.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/*
22
* @Author: yanjun.zsj
3-
* @LastEditors: yanjun.zsj
3+
* @LastEditors : yanjun.zsj
44
* @Date: 2019-03-11 16:43:26
5-
* @LastEditTime: 2019-11-21 17:51:13
5+
* @LastEditTime : 2020-01-19 15:21:57
66
*/
77
/* global React, ReactDOM */
88
const sourceCols = [
@@ -102,7 +102,8 @@ class App extends React.PureComponent {
102102
sourceData: data
103103
});
104104
},
105-
columns: sourceCols
105+
columns: sourceCols,
106+
mutiple: true
106107
},
107108
target: {
108109
data: targetData,
@@ -111,7 +112,8 @@ class App extends React.PureComponent {
111112
targetData: data
112113
});
113114
},
114-
columns: targetCols
115+
columns: targetCols,
116+
mutiple: true
115117
},
116118
relation: this.state.relation,
117119
// onDrawStart: (source, relation) => {
@@ -128,7 +130,7 @@ class App extends React.PureComponent {
128130
relation
129131
});
130132
},
131-
isSort: true,
133+
isSort: true
132134

133135
};
134136
return <div>

package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-field-mapping",
3-
"version": "1.0.3",
3+
"version": "1.0.5",
44
"description": "基于react的表字段映射组件",
55
"scripts": {
66
"check": "jsinspect ./src",
@@ -57,13 +57,13 @@
5757
"cross-env": "^6.0.0",
5858
"css-loader": "^3.2.0",
5959
"less-loader": "^5.0.0",
60+
"lodash": "^4.17.15",
61+
"react": "^16.8.4",
62+
"react-dom": "^16.8.4",
63+
"sortablejs": "^1.7.0",
6064
"style-loader": "^1.0.0",
6165
"url-loader": "^2.1.0",
6266
"webpack": "^4.40.2",
63-
"webpack-cli": "^3.3.9",
64-
"lodash": "^4.17.11",
65-
"react": "^16.8.4",
66-
"react-dom": "^16.8.4",
67-
"sortablejs": "^1.7.0"
67+
"webpack-cli": "^3.3.9"
6868
}
6969
}

src/Columns.jsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {Component} from 'react';
2+
import PropTypes from 'prop-types';
23
import { isElement } from 'react-dom/test-utils';
34

45
class Columns extends Component {
@@ -43,4 +44,13 @@ class Columns extends Component {
4344
}
4445
}
4546

47+
Columns.propTypes = {
48+
columns: PropTypes.array.isRequired,
49+
columnOpt: PropTypes.func.isRequired,
50+
sorting: PropTypes.bool.isRequired,
51+
item: PropTypes.object.isRequired,
52+
index: PropTypes.number.isRequired,
53+
type: PropTypes.string.isRequired,
54+
edit: PropTypes.bool.isRequired
55+
};
4656
export default Columns;

src/drawLines.jsx

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* @date 2018.11
33
*/
44
import {Component} from 'react';
5+
import PropTypes from 'prop-types';
56
import { getOffset } from './util.js';
67
import Line from './line.jsx';
78
import _ from 'lodash';
@@ -32,11 +33,19 @@ class DrawLines extends Component {
3233
const box = document.querySelector('.react-field-mapping-box');
3334
let scrollTop = 0;
3435
let scrollLeft = 0;
36+
let sourceDom = null;
3537
document.documentElement.onmousedown = (event) => {
3638
const eventDom = event.target;
39+
sourceDom = eventDom;
3740
const className = eventDom && eventDom.className;
3841
if (className && typeof className === "string" && className.indexOf("source-column-icon") > -1) {
3942
event.preventDefault();
43+
const relation = _.assign([], me.props.relation);
44+
if(!me.props.sourceMutiple && _.find(relation, (o) => {
45+
return o.source.key === me.domOperate(eventDom).key;
46+
})) {
47+
return;
48+
}
4049
if(this.baseXY !== getOffset(this.drawEle)) {
4150
this.baseXY = getOffset(this.drawEle);
4251
}
@@ -45,7 +54,7 @@ class DrawLines extends Component {
4554
const sourceData = _.find(me.props.sourceData, (o) => {
4655
return o.key === this.domOperate(eventDom).key;
4756
});
48-
me.props.onDrawStart && me.props.onDrawStart(sourceData, me.props.relation);
57+
me.props.onDrawStart(sourceData, me.props.relation);
4958
me.props.changeIconStatus(sourceData);
5059
me.setState({
5160
startX: this.domOperate(eventDom).left,
@@ -64,7 +73,7 @@ class DrawLines extends Component {
6473
};
6574
document.documentElement.onmousemove = (event) => {
6675
if (this.state.drawing) {
67-
me.props.onDrawing && me.props.onDrawing(me.state.sourceData, me.props.relation);
76+
me.props.onDrawing(me.state.sourceData, me.props.relation);
6877
me.setState({
6978
endX: event.pageX - this.baseXY.left + scrollLeft,
7079
endY: event.pageY - this.baseXY.top + scrollTop
@@ -78,11 +87,14 @@ class DrawLines extends Component {
7887
const className = eventDom && eventDom.className;
7988
if (className && typeof className === "string" && className.indexOf("target-column-icon") > -1) {
8089
const relation = _.assign([], me.props.relation);
81-
if(_.find(relation, (o) => {
90+
if(!me.props.targetMutiple && _.find(relation, (o) => {// target不允许映射多次
8291
return o.target.key === me.domOperate(eventDom).key;
92+
}) || _.find(relation, (o) => { // 过滤连线已存在的情况
93+
return o.target.key === me.domOperate(eventDom).key && o.source.key === me.domOperate(sourceDom).key;
8394
})) {
8495
me.props.changeIconStatus();
8596
me.setState({...defaultState});
97+
sourceDom = null;
8698
return;
8799
}
88100
const targetData = _.find(me.props.targetData, (o) => {
@@ -100,8 +112,9 @@ class DrawLines extends Component {
100112
...targetData
101113
}
102114
});
103-
me.props.onDrawEnd && me.props.onDrawEnd(sourceData, targetData, relation);
115+
me.props.onDrawEnd(sourceData, targetData, relation);
104116
me.props.onChange(relation);
117+
sourceDom = null;
105118
}
106119
me.props.changeIconStatus();
107120
me.setState({...defaultState});
@@ -133,7 +146,7 @@ class DrawLines extends Component {
133146
}
134147
render() {
135148
const { startX, startY, drawing, endX, endY } = this.state;
136-
const { relation, currentRelation, edit } = this.props;
149+
const { relation, currentRelation, edit, closeIcon } = this.props;
137150
return <div className="lines-area" ref={me => {this.drawEle = me;}}>
138151
<svg width="100%" height="100%" version="1.1"
139152
xmlns="http://www.w3.org/2000/svg">
@@ -160,6 +173,7 @@ class DrawLines extends Component {
160173
endY={item.target.y}
161174
data={item}
162175
edit={edit}
176+
closeIcon={closeIcon}
163177
toTop={this.topLine.bind(this)}
164178
currentRelation={currentRelation}
165179
removeRelation={this.removeRelation.bind(this)}
@@ -179,4 +193,24 @@ class DrawLines extends Component {
179193
}
180194
}
181195

196+
DrawLines.propTypes = {
197+
sourceData: PropTypes.array.isRequired,
198+
targetData: PropTypes.array.isRequired,
199+
sourceMutiple: PropTypes.bool.isRequired,
200+
targetMutiple: PropTypes.bool.isRequired,
201+
onDrawStart: PropTypes.func,
202+
onDrawing: PropTypes.func,
203+
onDrawEnd: PropTypes.func,
204+
relation: PropTypes.array.isRequired,
205+
edit: PropTypes.bool.isRequired,
206+
currentRelation: PropTypes.object.isRequired,
207+
onChange: PropTypes.func.isRequired,
208+
changeIconStatus: PropTypes.func.isRequired,
209+
closeIcon: PropTypes.string
210+
};
211+
DrawLines.defaultProps = {
212+
onDrawStart: () => {},
213+
onDrawing: () => {},
214+
onDrawEnd: () => {}
215+
};
182216
export default DrawLines;

src/fieldMapping.jsx

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ class FieldMapping extends Component {
6767
changeSource(oldIndex, newIndex) {
6868
const {
6969
source: {
70-
data: sourceData,
71-
onChange
70+
data: sourceData = [],
71+
onChange = () => {}
7272
}
7373
} = this.props;
7474
let data = _.assign([], sourceData);
@@ -84,8 +84,8 @@ class FieldMapping extends Component {
8484
changeTarget(oldIndex, newIndex) {
8585
const {
8686
target: {
87-
data: targetData,
88-
onChange
87+
data: targetData = [],
88+
onChange = () => {}
8989
}
9090
} = this.props;
9191
let data = _.assign([], targetData);
@@ -102,22 +102,24 @@ class FieldMapping extends Component {
102102
const { relation, iconStatus, currentRelation } = this.state;
103103
const {
104104
source: {
105-
data: sourceData,
106-
columns: sourceCols
105+
data: sourceData = [],
106+
columns: sourceCols = [],
107+
mutiple: sourceMutiple = false
107108
},
108109
target: {
109-
data: targetData,
110-
columns: targetCols
110+
data: targetData = [],
111+
columns: targetCols = [],
112+
mutiple: targetMutiple = false
111113
},
112114
className = "",
113115
style = {},
114116
isSort = false,
115117
onDrawStart,
116118
onDrawing,
117119
onDrawEnd,
118-
edit
120+
edit,
121+
closeIcon
119122
} = this.props;
120-
121123
const sourceOpt = {
122124
ref: (me) => {this.sourceCom = me;},
123125
iconStatus,
@@ -145,11 +147,14 @@ class FieldMapping extends Component {
145147
const drawLinesOpt = {
146148
sourceData,
147149
targetData,
150+
sourceMutiple,
151+
targetMutiple,
148152
onDrawStart,
149153
onDrawing,
150154
onDrawEnd,
151155
relation,
152156
edit,
157+
closeIcon,
153158
currentRelation,
154159
onChange: this.changeRelation.bind(this),
155160
changeIconStatus: this.changeIconStatus.bind(this)
@@ -168,6 +173,7 @@ FieldMapping.propTypes = {
168173
source: PropTypes.shape({
169174
data: PropTypes.array, // required param key
170175
onChange: PropTypes.func, // 源表data改变后触发,目前只有排序会触发。isSort开启后,必须在外层同步。
176+
mutiple: PropTypes.bool, //是否允许一个source连接多个target
171177
columns: PropTypes.arrayOf(PropTypes.shape({
172178
title: PropTypes.string.isRequired,
173179
key: PropTypes.string.isRequired,
@@ -183,6 +189,7 @@ FieldMapping.propTypes = {
183189
target: PropTypes.shape({
184190
data: PropTypes.array, // required param key
185191
onChange: PropTypes.func, // 目标表data改变后触发,目前只有排序会触发。
192+
mutiple: PropTypes.bool, //是否允许多个source连接一个target
186193
columns: PropTypes.arrayOf(PropTypes.shape({
187194
title: PropTypes.string.isRequired,
188195
key: PropTypes.string.isRequired,
@@ -201,19 +208,22 @@ FieldMapping.propTypes = {
201208
onDrawStart: PropTypes.func,// function(params=source, relation)
202209
onDrawing: PropTypes.func,// function(params=source, relation)
203210
onDrawEnd: PropTypes.func,// function(params=source, relation)
204-
edit: PropTypes.bool // 是否能操作线条编辑 default true
211+
edit: PropTypes.bool, // 是否能操作线条编辑 default true
212+
closeIcon: PropTypes.string // 关闭线条的icon url,不传用默认的关闭按钮
205213
};
206214
FieldMapping.defaultProps = {
207215
relation: [],
208216
source: {
209217
data: [],
210218
onChange: () => {},
211-
columns: []
219+
columns: [],
220+
mutiple: false
212221
},
213222
target: {
214223
data: [],
215224
onChange: () => {},
216-
columns: []
225+
columns: [],
226+
mutiple: false
217227
},
218228
edit: true
219229
};

src/line.jsx

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
* @date 2018.11
33
*/
44
import {Component} from 'react';
5+
import PropTypes from 'prop-types';
6+
57
const iconSize = [12, 12];
68
class Line extends Component {
79
constructor(props) {
@@ -18,7 +20,8 @@ class Line extends Component {
1820
endY = 0,
1921
currentRelation,
2022
data,
21-
edit
23+
edit,
24+
closeIcon
2225
} = this.props;
2326
return <g className={`path-end ${(currentRelation === data) ? "active" : ""} ${edit ? '' : 'disabled'}`} onMouseOver={() => {
2427
edit && this.props.toTop(this.props.data);
@@ -36,9 +39,20 @@ class Line extends Component {
3639
y={(endY + startY - iconSize[1])/2}
3740
width={iconSize[0]}
3841
height={iconSize[1]}
39-
xlinkHref="//img.alicdn.com/tfs/TB1laCNsXYqK1RjSZLeXXbXppXa-200-200.png" />
42+
xlinkHref={closeIcon || "//img.alicdn.com/tfs/TB1laCNsXYqK1RjSZLeXXbXppXa-200-200.png"} />
4043
</g>;
4144
}
4245
}
43-
46+
Line.propTypes = {
47+
startX: PropTypes.number.isRequired,
48+
startY: PropTypes.number.isRequired,
49+
endX: PropTypes.number.isRequired,
50+
endY: PropTypes.number.isRequired,
51+
data: PropTypes.object.isRequired,
52+
edit: PropTypes.bool.isRequired,
53+
toTop: PropTypes.func.isRequired,
54+
currentRelation: PropTypes.object.isRequired,
55+
removeRelation: PropTypes.func.isRequired,
56+
closeIcon: PropTypes.string
57+
};
4458
export default Line;

0 commit comments

Comments
 (0)