1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
import { computed, IReactionDisposer, reaction } from "mobx";
import { observer } from "mobx-react";
import { Utils } from "../../../../Utils";
import { DocumentManager } from "../../../util/DocumentManager";
import { DocumentView } from "../../nodes/DocumentView";
import { CollectionViewProps } from "../CollectionSubView";
import "./CollectionFreeFormLinksView.scss";
import { CollectionFreeFormLinkView } from "./CollectionFreeFormLinkView";
import React = require("react");
import { Doc } from "../../../../new_fields/Doc";
import { Cast, FieldValue, NumCast, StrCast } from "../../../../new_fields/Types";
import { listSpec } from "../../../../new_fields/Schema";
import { List } from "../../../../new_fields/List";
import { Id } from "../../../../new_fields/RefField";
@observer
export class CollectionFreeFormLinksView extends React.Component<CollectionViewProps> {
_brushReactionDisposer?: IReactionDisposer;
componentDidMount() {
this._brushReactionDisposer = reaction(() => Cast(this.props.Document[this.props.fieldKey], listSpec(Doc), []).map(doc => NumCast(doc.x)),
() => {
let views = Cast(this.props.Document[this.props.fieldKey], listSpec(Doc), []).filter(doc => StrCast(doc.backgroundLayout, "").indexOf("istogram") !== -1);
for (let i = 0; i < views.length; i++) {
for (let j = 0; j < views.length; j++) {
let srcDoc = views[j];
let dstDoc = views[i];
let x1 = NumCast(srcDoc.x);
let x1w = NumCast(srcDoc.width, -1);
let x2 = NumCast(dstDoc.x);
let x2w = NumCast(dstDoc.width, -1);
if (x1w < 0 || x2w < 0 || i === j) {
continue;
}
let dstTarg = dstDoc;
let srcTarg = srcDoc;
let findBrush = (field: List<Doc>) => field.findIndex(brush => {
let bdocs = brush ? Cast(brush.brushingDocs, listSpec(Doc), []) : [];
return (bdocs.length && ((bdocs[0] === dstTarg && bdocs[1] === srcTarg)) ? true : false);
});
let brushAction = (field: List<Doc>) => {
let found = findBrush(field);
if (found !== -1) {
console.log("REMOVE BRUSH " + srcTarg.Title + " " + dstTarg.Title);
field.splice(found, 1);
}
};
if (Math.abs(x1 + x1w - x2) < 20) {
let linkDoc: Doc = new Doc();
linkDoc.title = "Histogram Brush";
linkDoc.linkDescription = "Brush between " + StrCast(srcTarg.title) + " and " + StrCast(dstTarg.Title);
linkDoc.brushingDocs = new List([dstTarg, srcTarg]);
brushAction = (field: List<Doc>) => {
if (findBrush(field) === -1) {
console.log("ADD BRUSH " + srcTarg.Title + " " + dstTarg.Title);
(findBrush(field) === -1) && field.push(linkDoc);
}
};
}
let dstBrushDocs = Cast(dstTarg.brushingDocs, listSpec(Doc));
if (dstBrushDocs === undefined) {
dstTarg.brushingDocs = dstBrushDocs = new List<Doc>();
}
let srcBrushDocs = Cast(srcTarg.brushingDocs, listSpec(Doc));
if (srcBrushDocs === undefined) {
srcTarg.brushingDocs = srcBrushDocs = new List<Doc>();
}
brushAction(dstBrushDocs);
brushAction(srcBrushDocs);
}
}
});
}
componentWillUnmount() {
if (this._brushReactionDisposer) {
this._brushReactionDisposer();
}
}
documentAnchors(view: DocumentView) {
let equalViews = [view];
let containerDoc = FieldValue(Cast(view.props.Document.annotationOn, Doc));
if (containerDoc) {
equalViews = DocumentManager.Instance.getDocumentViews(containerDoc.proto!);
}
if (view.props.ContainingCollectionView) {
let collid = view.props.ContainingCollectionView.props.Document[Id];
Cast(this.props.Document[this.props.fieldKey], listSpec(Doc), []).
filter(child =>
child[Id] === collid).map(view =>
DocumentManager.Instance.getDocumentViews(view).map(view =>
equalViews.push(view)));
}
return equalViews.filter(sv => sv.props.ContainingCollectionView && sv.props.ContainingCollectionView.props.Document === this.props.Document);
}
@computed
get uniqueConnections() {
let connections = DocumentManager.Instance.LinkedDocumentViews.reduce((drawnPairs, connection) => {
let srcViews = this.documentAnchors(connection.a);
let targetViews = this.documentAnchors(connection.b);
let possiblePairs: { a: Doc, b: Doc, }[] = [];
srcViews.map(sv => targetViews.map(tv => possiblePairs.push({ a: sv.props.Document, b: tv.props.Document })));
possiblePairs.map(possiblePair =>
drawnPairs.reduce((found, drawnPair) => {
let match = (possiblePair.a === drawnPair.a && possiblePair.b === drawnPair.b);
if (match && !drawnPair.l.reduce((found, link) => found || link[Id] === connection.l[Id], false)) {
drawnPair.l.push(connection.l);
}
return match || found;
}, false)
||
drawnPairs.push({ a: possiblePair.a, b: possiblePair.b, l: [connection.l] })
);
return drawnPairs;
}, [] as { a: Doc, b: Doc, l: Doc[] }[]);
return connections.map(c => <CollectionFreeFormLinkView key={Utils.GenerateGuid()} A={c.a} B={c.b} LinkDocs={c.l}
removeDocument={this.props.removeDocument} addDocument={this.props.addDocument} />);
}
render() {
return (
<div className="collectionfreeformlinksview-container">
<svg className="collectionfreeformlinksview-svgCanvas">
{this.uniqueConnections}
</svg>
{this.props.children}
</div>
);
}
}
|