aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/DataVizBox/components/TableBox.tsx
blob: 500e7b639e4e01384184a90dfb7986181ec367be (plain)
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
import { action, computed } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc } from '../../../../../fields/Doc';
import { Id } from '../../../../../fields/FieldSymbols';
import { List } from '../../../../../fields/List';
import { emptyFunction, returnFalse, setupMoveUpEvents, Utils } from '../../../../../Utils';
import { DragManager } from '../../../../util/DragManager';
import { DocumentView } from '../../DocumentView';
import { DataVizView } from '../DataVizBox';
import { LinkManager } from '../../../../util/LinkManager';
import { DocCast } from '../../../../../fields/Types';

interface TableBoxProps {
    rootDoc: Doc;
    pairs: { [key: string]: any }[];
    selectAxes: (axes: string[]) => void;
    axes: string[];
    docView?: () => DocumentView | undefined;
}

@observer
export class TableBox extends React.Component<TableBoxProps> {

    @computed get _tableData() {
        if (this.incomingLinks.length! <= 0) return this.props.pairs;
        return this.props.pairs?.filter(pair => (Array.from(Object.keys(pair)).some(key => pair[key] && key.startsWith('select'))))
    }

    @computed get incomingLinks() {
        return LinkManager.Instance.getAllRelatedLinks(this.props.rootDoc) // out of all links
            .filter(link => {
                return link.link_anchor_1 == this.props.rootDoc.draggedFrom}) // get links where this chart doc is the target of the link
            .map(link => DocCast(link.link_anchor_1)); // then return the source of the link
    }

    @computed get columns() {
        // return this.props.pairs.length ? Array.from(Object.keys(this.props.pairs[0])) : [];
        return this._tableData.length ? Array.from(Object.keys(this._tableData[0])) : [];
    }

    render() {
        return (
            <div className="table-container">
                <table className="table">
                    <thead>
                        <tr className="table-row">
                            {this.columns
                                .filter(col => !col.startsWith('select'))
                                .map(col => {
                                    const header = React.createRef<HTMLElement>();
                                    return (
                                        <th
                                            key={this.columns.indexOf(col)}
                                            ref={header as any}
                                            style={{
                                                color: this.props.axes.slice().reverse().lastElement() === col ? 'green' : this.props.axes.lastElement() === col ? 'red' : undefined,
                                                fontWeight: this.props.axes.includes(col) ? 'bolder' : 'normal',
                                            }}
                                            onPointerDown={e => {
                                                const downX = e.clientX;
                                                const downY = e.clientY;
                                                setupMoveUpEvents(
                                                    {},
                                                    e,
                                                    e => {
                                                        const sourceAnchorCreator = () => this.props.docView?.()!.rootDoc!;
                                                        const targetCreator = (annotationOn: Doc | undefined) => {
                                                            const embedding = Doc.MakeEmbedding(this.props.docView?.()!.rootDoc!);
                                                            embedding._dataVizView = DataVizView.LINECHART;
                                                            embedding._data_vizAxes = new List<string>([col, col]);
                                                            embedding._draggedFrom = this.props.docView?.()!.rootDoc!;
                                                            embedding.annotationOn = annotationOn; //this.props.docView?.()!.rootDoc!;
                                                            return embedding;
                                                        };
                                                        if (this.props.docView?.() && !Utils.isClick(e.clientX, e.clientY, downX, downY, Date.now())) {
                                                            DragManager.StartAnchorAnnoDrag([header.current!], new DragManager.AnchorAnnoDragData(this.props.docView()!, sourceAnchorCreator, targetCreator), downX, downY, {
                                                                dragComplete: e => {
                                                                    if (!e.aborted && e.annoDragData && e.annoDragData.linkSourceDoc && e.annoDragData.dropDocument && e.linkDocument) {
                                                                        e.linkDocument.link_displayLine = true;
                                                                        e.linkDocument.link_matchEmbeddings = true;
                                                                        // e.annoDragData.linkSourceDoc.followLinkToggle = e.annoDragData.dropDocument.annotationOn === this.props.rootDoc;
                                                                        // e.annoDragData.linkSourceDoc.followLinkZoom = false;
                                                                    }
                                                                },
                                                            });
                                                            return true;
                                                        }
                                                        return false;
                                                    },
                                                    emptyFunction,
                                                    action(e => {
                                                        const newAxes = this.props.axes;
                                                        if (newAxes.includes(col)) {
                                                            newAxes.splice(newAxes.indexOf(col), 1);
                                                        } else if (newAxes.length >= 1) {
                                                            newAxes[1] = col;
                                                        } else {
                                                            newAxes[0] = col;
                                                        }
                                                        this.props.selectAxes(newAxes);
                                                    })
                                                );
                                            }}>
                                            {col}
                                        </th>
                                    );
                                })}
                        </tr>
                    </thead>
                    <tbody>
                        {this._tableData?.map((p, i) => {
                            return (
                                <tr key={i} className="table-row" onClick={action(e => (p['select' + this.props.docView?.()?.rootDoc![Id]] = !p['select' + this.props.docView?.()?.rootDoc![Id]]))}>
                                    {this.columns.map(col => (
                                        <td key={this.columns.indexOf(col)} style={{ fontWeight: p['select' + this.props.docView?.()?.rootDoc![Id]] ? 'bold' : '' }}>
                                            {p[col]}
                                        </td>
                                    ))}
                                </tr>
                            );
                        })}
                    </tbody>
                </table>
            </div>
        );
    }
}